Sixty years since Silent Spring: towards a balanced view of the organochlorine pesticide literature

In this Rmarkdown document we provide the following workflow:

  • Objective 0. To investigate current literature characteristics such as time trend

  • Objective 1 . To explore the various characteristics of the organochlorine pesticides literature such as the pesticides used, the impacts elicited in response and the subjects that were investigated.

  • Objective 2. To investigate current methodological practices within meta-analysis investigating the impacts of organochlorine pesticides. We will investigate how they currently search for existing literature, which effect sizes are used, how they adjust for heterogeneity and how they account for risk of bias.

  • Objective 3 - To investigate current reporting practices in existing meta-analyses examining the impacts of organochlorine pesticides.

  • Objective 4 - To investigate the research outputs across different countries and continents and investigate the degree of cross-country collaboration.

Load packages and data

Load Packages

rm(list = ls())
pacman::p_load(tidyverse,
hrbrthemes, 
patchwork,
here,
stringr,
knitr,
formatR,
forcats,
ggplot2,
bibliometrix,
igraph,
stringi,
stringdist,
circlize,
ggalluvial)
knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)

Load data

Manually extracted pilot data is stored in five separate .csv files representing different aspects of the data (extracted via structured predefined Google Forms - one per table).

Bibliographic data records are exported from Scopus (including cited references field) in .bib format and locally saved as scopus.bib.

sd <- read_csv(here("data","ocp_srm_study_details.csv"), skip = 0)
ocp <- read_csv(here("data", "ocp_srm_ocp_details.csv"), skip = 0)
sub <- read_csv(here("data", "ocp_srm_subject_details.csv"), skip =0)
im <- read_csv(here("data", "ocp_srm_impact_details.csv"), skip =0)
sp <- read_csv(here("data", "ocp_srm_species_details.csv"), skip =0)
bib_sco <- convert2df(here("data","bib_sco.bib"), dbsource = "scopus", format = "bibtex")
## 
## Converting your scopus collection into a bibliographic dataframe
## 
## Done!
## 
## 
## Generating affiliation field tag AU_UN from C1:  Done!

Objective 0. To investigate current literature characteristics such as time trend

Figure x - Total number of meta-analysis per subject

# Join the study and subject datasets
sd_sub <- left_join(sd, sub, by = "study_id")

# Create the annual count plot
fig1a <- sd_sub %>%
  mutate(subjects = strsplit(subject, ",\\s+")) %>%
  unnest(subjects) %>%
  count(publication_year, subjects) %>%
  group_by(subjects = reorder(subjects, n)) %>%
  ggplot(aes(x = as.factor(publication_year), y = n, fill = subjects)) +
  geom_bar(stat = "identity", position = "stack", alpha = 0.7) +
  scale_y_continuous("Annual Article Count", limits = c(0,15)) +
  theme_minimal() +
  labs(x = "Year", y = "Article Count") +
  theme(panel.grid.major.y = element_line(color = "gray", linetype = "dashed"),
        panel.grid.minor.y = element_blank(),
        axis.line.x = element_line(size = 1.2),
        axis.line.y = element_line(size = 1.2),
        axis.title.x = element_text(size = 14, face = "bold"),
        axis.title.y = element_text(size = 14, face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1, size = 10, color = "#666666"),
        axis.text.y = element_text(size = 10, color = "#666666"),
        plot.title = element_text(size = 20, face = "bold"),
        plot.subtitle = element_text(size = 14),
        plot.caption = element_text(size = 10, hjust = 0)) +
  scale_fill_brewer(palette = "Dark2") +
  labs(fill = "Subject Category") +
  guides(fill = guide_legend(override.aes = list(size=3)))

# Create the cumulative count plot
fig1b <-  sd_sub %>%
  mutate(subjects = strsplit(subject, ",\\s+")) %>%
  unnest(subjects) %>%
  count(publication_year, subjects) %>%
  group_by(subjects = reorder(subjects, n)) %>%
  mutate(n_cumulative = cumsum(n)) %>%
  ggplot(aes(x = publication_year, y = n_cumulative, fill = subjects)) +
  geom_area(size = 1.2, alpha = 0.7) +
  scale_y_continuous("Cumulative Article Count", limits = c(0,115)) +
  scale_x_continuous(breaks = seq(min(sd_sub$publication_year), max(sd_sub$publication_year), by = 1)) +
  theme_minimal() +
  labs(x = "Year", y = "Cumulative Article Count") +
  theme(panel.grid.major.y = element_line(color = "gray", linetype = "dashed"),
        panel.grid.minor.y = element_blank(),
        axis.line.x = element_line(size = 1.2),
        axis.line.y = element_line(size = 1.2),
        axis.title.x = element_text(size = 14, face = "bold"),
        axis.title.y = element_text(size = 14, face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1, size = 10, color = "#666666"),
        axis.text.y = element_text(size = 10, color = "#666666"),
        plot.title = element_text(size = 20, face = "bold"),
        plot.subtitle = element_text(size = 14),
        plot.caption = element_text(size = 10, hjust = 0)) +
  scale_fill_brewer(palette = "Dark2") +
  labs(fill = "Subject") +
  guides(fill = guide_legend(override.aes = list(size=3)))

# Combine the two plots
fig1 <- fig1a /  fig1b

fig1

Objective 1. To characterise the organochlorine pesticides literature such as the pesticides used, the impacts elicited in response and the subjects that were investigated.

Figure x - Total count of each organochlorine used in meta-analysis

# Transform the data 
ocp_count <-
  ocp %>% 
  separate_rows(ocp, sep = ",\\s+") %>% 
  count(ocp) %>% 
  filter(!is.na(ocp)) %>% # filter out NA 
 filter(ocp != "not reported") %>% 
  arrange(desc(n)) %>% 
  mutate(ocp = ifelse(n <= 3, "other", as.character(ocp))) %>%  ## I NEED TO LIST ALL THE OTHERS HERE WITH THEIR COUNTS
  group_by(ocp) %>% 
  summarise(n =sum(n))

ocp_pct <- ocp_count %>%
  mutate(proportion = n/sum(ocp_count$n),
         percentage = proportion*100)

# Create the count plot 
ocp_count %>%
  ggplot(aes(x = n, y = reorder(ocp, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.6, alpha = 0.7) +
  geom_text(data = ocp_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.9, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n + 0.5, y = reorder(ocp, n)), vjust = 0.5, hjust = 0, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, 45)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 10),
        axis.text.x = element_text(size = 10),
        axis.line.x = element_line(color = "gray", size = 0.5),
        axis.line.y = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.y = element_blank(),
        axis.title.x = element_text(size = 12),
        axis.title.y = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        legend.position = "none")

Figure x - Total proportion of meta-analysis per subject

note: some meta-analysis may contribute to multiple sections if involve multiple subjects

# Calculate total count for each category
subject_count <- 
  sub %>% 
    separate_rows(subject, sep = ",\\s+") %>% 
    count(subject)

# Calculate proportion and percentage for each category
subject_pct <- subject_count %>%
  mutate(proportion = n/sum(subject_count$n),
         percentage = proportion*100)

# Create the count plot
subject_count %>%
  ggplot(aes(x = n, y = reorder(subject, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = subject_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n + 0.5, y = reorder(subject, n)), vjust = 0.5, hjust = 0, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, 90)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 10),
        axis.text.x = element_text(size = 10),
        axis.line.x = element_line(color = "gray", size = 0.5),
        axis.line.y = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.y = element_blank(),
        axis.title.x = element_text(size = 12),
        axis.title.y = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        legend.position = "none")

# Calculate total count for each category
impact_count <- 
  im %>% 
    separate_rows(impact, sep = ",\\s+") %>% 
    count(impact) %>% 
  filter(impact != "NA") %>%
  mutate(impact = ifelse(n<= 1, "other", as.character(impact))) %>% 
    group_by(impact) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
impact_pct <- impact_count %>%
  mutate(proportion = n/sum(impact_count$n),
         percentage = proportion*100)

# Generate a graph
impact_count %>%
  ggplot(aes(x = n, y = reorder(impact, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = impact_pct, aes(label = paste0("(", round(percentage, 1), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(impact, n)), vjust = 0.5, hjust = -0.2, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, max(impact_count$n)*1.2)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

Alluvial plot of ocp, subjecty and impact

# Transform the data 
df <- im %>%
  left_join(ocp, by = "study_id") %>%
  left_join(sub, by = "study_id") %>%
  separate_rows(subject, sep = ",\\s+") %>% 
  separate_rows(ocp, sep = ",\\s+") %>% 
  separate_rows(impact, sep = ",\\s+") %>%
  mutate(ocp_convert = case_when( # Rename isomers and metabolites to parent chemical (besides DDT, DDD and DDE which are just isomers)
    grepl("DDT", ocp, ignore.case = TRUE) ~ "DDT", 
    grepl("DDD", ocp, ignore.case = TRUE) ~ "DDD", 
    grepl("DDE", ocp, ignore.case = TRUE) ~ "DDE", 
    grepl("HCH|Hexachloro|BHC|Lindane", ocp, ignore.case = TRUE) ~ "Hexachlorohexane", 
    grepl("Chlordane", ocp, ignore.case = TRUE) ~ "Chlordane",  
    grepl("Endosulfan", ocp, ignore.case = TRUE) ~ "Endosulfan", 
    grepl("Nonachlor", ocp, ignore.case = TRUE) ~ "Nonachlore", 
    grepl("Heptachlor", ocp, ignore.case = TRUE) ~ "Heptachlor",
    grepl("TCDD", ocp, ignore.case = TRUE) ~ "TCDD", 
    grepl("Endrin", ocp, ignore.case = TRUE) ~ "Endrin",
    TRUE ~ ocp)) %>%
  filter(!grepl("not reported", ocp_convert, ignore.case = TRUE)) %>%
  group_by(ocp_convert, subject, impact) %>%
  summarise(freq = n(), .groups = 'drop') %>%
  group_by(ocp_convert) %>%
  filter(sum(freq) > 2) %>% # filtered for ocp's with more than two occurrences 
  group_by(impact) %>% 
  filter(sum(freq) > 3) %>% # filter for impacts with more than three occurrences 
  mutate(subject = factor(subject, levels = c("environment", "non-human animal", "human"), ordered = TRUE))


# Plot alluvial plot between ocp, subject and impact 
ggplot(data = df,
       aes(axis1 = ocp_convert, axis2 = subject, axis3 = impact, y = freq)) +
  scale_x_discrete(limits = c("Organochlorine Pesticide", "Subject", "Impact"), expand = c(.05, .10)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = subject)) +
  geom_stratum(width = 1/2, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal() +
  scale_fill_brewer(palette = "Dark2", name = "Subject Category")

Objective 2. To investigate current methodological practices within meta-analysis investigating the impacts of organochlorine pesticides. We will investigate how they currently search for existing literature, which effect sizes are used, how they adjust for heterogeneity and how they account for risk of bias.

Figure x - Total count of each database used to search the literature within each meta-analysis

# Calculate the total count for each category
database_count <- sd %>% 
  separate_rows(database_search, sep = ",\\s+") %>% 
  count(database_search) %>% 
  filter(database_search != "not reported") %>% 
  arrange(desc(n)) %>% 
  mutate(database_search = ifelse(n<= 2, "other", as.character(database_search))) %>% 
    group_by(database_search) %>%
  summarise(n = sum(n))


# Calculate proportion and percentage for each category
database_pct <- database_count %>%
  mutate(proportion = n / sum(database_count$n),
         percentage = proportion * 100)

# Create the count plot
database_count %>%
  ggplot(aes(x = n, y = reorder(database_search, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = database_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9),vjust = 0.5, hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(database_search, n)), vjust = 0.5, hjust = -0.1, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, 60)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
database_alluvial <- sd %>% 
    separate_rows(database_search, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    group_by(Journal_Citation_Report_Category, database_search) %>% 
    count(database_search, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(database_search) %>% 
    filter(sum(freq) > 2)  # filtered for scientic databases  with more than two occurrences 

# Create the Alluvial plot
ggplot(database_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = database_search)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Database Search"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal() 

Figure x - Total count of each effect size measure used within each meta-analysis

# Calculate the total count for each category
effectsize_count <- sd %>% 
  separate_rows(effect_size, sep = ",\\s+") %>% 
  count(effect_size) %>%
  filter(effect_size != "NA") %>%
  mutate(effect_size = ifelse(n<= 2, "other", as.character(effect_size))) %>% 
    group_by(effect_size) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
effectsize_pct <- effectsize_count %>%
  mutate(proportion = n / sum(effectsize_count$n),
         percentage = proportion * 100)

# Create the count plot
effectsize_count %>%
  ggplot(aes(x = n, y = reorder(effect_size, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = effectsize_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(effect_size, n)), vjust = 0.5, hjust = -0.2, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, 60)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
effectsize_alluvial <- sd %>% 
    separate_rows(effect_size, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(effect_size)) %>%
    group_by(Journal_Citation_Report_Category, effect_size) %>% 
    count(effect_size, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(effect_size) #  %>% 
  #   filter(sum(freq) > 2)  # filtered for scientific databases  with more than two occurrences 


# Create the Alluvial plot
ggplot(effectsize_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = effect_size)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Effect Size"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure x - Total count of each software used to analyse the data within each meta-analysis

# Calculate the total count for each category
software_count <- sd %>% 
  separate_rows(software_analysis, sep = ",\\s+") %>% 
  count(software_analysis) %>%
  filter(software_analysis != "NA") %>%
  mutate(software_analysis = ifelse(n<= 2, "other", as.character(software_analysis))) %>% 
    group_by(software_analysis) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
software_pct <- software_count %>%
  mutate(proportion = n / sum(software_count$n),
         percentage = proportion * 100)

# Create the count plot
software_count %>%
  ggplot(aes(x = n, y = reorder(software_analysis, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = software_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(software_analysis, n)), vjust = 0.5, hjust = -0.2, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, 60)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
software_analysis_alluvial <- sd %>% 
    separate_rows(software_analysis, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(software_analysis)) %>%
    group_by(Journal_Citation_Report_Category, software_analysis) %>% 
    count(software_analysis, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(software_analysis)


# Create the Alluvial plot
ggplot(software_analysis_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = software_analysis)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Software Analysis"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure x - Total count of each heterogeneity test used within each meta-analysis

# Calculate the total count for each category
heterogeneity_count <- sd %>% 
  separate_rows(heterogeneity_assessment_method, sep = ",\\s+") %>% 
  count(heterogeneity_assessment_method) %>%
  filter(heterogeneity_assessment_method != "NA") %>%
  mutate(heterogeneity_assessment_method = ifelse(n<= 2, "other", as.character(heterogeneity_assessment_method))) %>% 
    group_by(heterogeneity_assessment_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
heterogeneity_pct <- heterogeneity_count %>%
  mutate(proportion = n / sum(heterogeneity_count$n),
         percentage = proportion * 100)

# Create the count plot
heterogeneity_count %>%
  ggplot(aes(x = n, y = reorder(heterogeneity_assessment_method, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = heterogeneity_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(heterogeneity_assessment_method, n)), vjust = 0.5, hjust = -0.2, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, 100)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
heterogeneity_alluvial <- sd %>% 
    separate_rows(heterogeneity_assessment_method, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(heterogeneity_assessment_method)) %>%
    group_by(Journal_Citation_Report_Category, heterogeneity_assessment_method) %>% 
    count(heterogeneity_assessment_method, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(heterogeneity_assessment_method)  

# Create the Alluvial plot
ggplot(heterogeneity_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = heterogeneity_assessment_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Heterogeneity Assessment Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure xx - Total count for each sensitivity analysis used in each meta-analysis

# Calculate the total count for each category
sensitivity_count <- sd %>% 
  separate_rows(sensitivity_analysis_method, sep = ",\\s+") %>% 
  count(sensitivity_analysis_method) %>%
  filter(sensitivity_analysis_method != "NA") %>%
  mutate(sensitivity_analysis_method = ifelse(n<= 1, "other", as.character(sensitivity_analysis_method))) %>% 
    group_by(sensitivity_analysis_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
sensitivity_pct <- sensitivity_count %>%
  mutate(proportion = n / sum(sensitivity_count$n),
         percentage = proportion * 100)

# Create the count plot
sensitivity_count %>%
  ggplot(aes(x = n, y = reorder(sensitivity_analysis_method, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = sensitivity_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(sensitivity_analysis_method, n)), vjust = 0.5, hjust = -0.2, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, 40)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
sensitivity_analysis_alluvial <- sd %>% 
    separate_rows(sensitivity_analysis_method, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(sensitivity_analysis_method)) %>%
    group_by(Journal_Citation_Report_Category, sensitivity_analysis_method) %>% 
    count(sensitivity_analysis_method, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(sensitivity_analysis_method)

# Create the Alluvial plot
ggplot(sensitivity_analysis_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = sensitivity_analysis_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Sensitivity Analysis Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure x - Total count of each type of between study bias investiagted in each meta-analysis

# Calculate the total count for each category
bias_type_count <- sd %>% 
  separate_rows(bias_assessment_type, sep = ",\\s+") %>% 
  count(bias_assessment_type) %>%
  filter(bias_assessment_type != "NA") %>%
  group_by(bias_assessment_type) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
bias_type_pct <- bias_type_count %>%
  mutate(proportion = n / sum(bias_type_count$n),
         percentage = proportion * 100)

# Create the count plot
bias_type_count %>%
  ggplot(aes(x = n, y = reorder(bias_assessment_type, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = bias_type_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(bias_assessment_type, n)), vjust = 0.5, hjust = -0.2, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, 75)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
bias_assessment_alluvial <- sd %>% 
    separate_rows(bias_assessment_type, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(bias_assessment_type)) %>%
    group_by(Journal_Citation_Report_Category, bias_assessment_type) %>% 
    count(bias_assessment_type, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(bias_assessment_type)

# Create the Alluvial plot
ggplot(bias_assessment_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = bias_assessment_type)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Bias Assessment Type"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure x - Total count for each statistical methodology to investigate within study bias used in each meta-analysis

# Calculate the total count for each category
bias_method_count <- sd %>% 
  separate_rows(bias_assessment_method, sep = ",\\s+") %>% 
  count(bias_assessment_method) %>%
  filter(bias_assessment_method != "NA") %>%
    group_by(bias_assessment_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
bias_method_pct <- bias_method_count %>%
  mutate(proportion = n / sum(bias_method_count$n),
         percentage = proportion * 100)

# Create the count plot
bias_method_count %>%
  ggplot(aes(x = n, y = reorder(bias_assessment_method, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = bias_method_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(bias_assessment_method, n)), vjust = 0.5, hjust = -0.2, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, 70)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
bias_assessment_alluvial <- sd %>% 
    separate_rows(bias_assessment_method, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(bias_assessment_method)) %>%
    group_by(Journal_Citation_Report_Category, bias_assessment_method) %>% 
    count(bias_assessment_method, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(bias_assessment_method)

# Create the Alluvial plot
ggplot(bias_assessment_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = bias_assessment_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Bias Assessment Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

# Calculate the total count for each category
rob_method_count <- sd %>% 
  separate_rows(rob_assessment_method, sep = ",\\s+") %>% 
  count(rob_assessment_method) %>%
  filter(rob_assessment_method != "NA") %>%
  group_by(rob_assessment_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
rob_method_pct <- rob_method_count %>%
  mutate(proportion = n / sum(rob_method_count$n),
         percentage = proportion * 100)

# Create the count plot
rob_method_count %>%
  ggplot(aes(x = n, y = reorder(rob_assessment_method, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = rob_method_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(rob_assessment_method, n)), vjust = 0.5, hjust = -0.2, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, 70)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
robmethod_alluvial <- sd %>% 
    separate_rows(rob_assessment_method, sep = ",\\s+") %>%
   # filter(!is.na(rob_assessment_method)) %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>%
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    group_by(Journal_Citation_Report_Category, rob_assessment_method) %>% 
    count(rob_assessment_method, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(rob_assessment_method) %>% 
    filter(sum(freq) > 2)  # filtered for scientic databases  with more than two occurrences 


# Create the Alluvial plot
ggplot(robmethod_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = rob_assessment_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "ROB Assessment Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure x - Total count for each methodology used to visualise the results of the meta-analsis

# Calculate the total count for each category
visualization_count <- sd %>% 
  separate_rows(visualization_method, sep = ",\\s+") %>% 
  count(visualization_method) %>%
  filter(visualization_method != "NA") %>%
  mutate(visualization_method = ifelse(n<= 2, "other", as.character(visualization_method))) %>% 
    group_by(visualization_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
visualization_pct <- visualization_count %>%
  mutate(proportion = n / sum(visualization_count$n),
         percentage = proportion * 100)

# Create the count plot
visualization_count %>%
  ggplot(aes(x = n, y = reorder(visualization_method, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = visualization_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(visualization_method, n)), vjust = 0.5, hjust = -0.2, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, 100)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

Figure x - Total count for each reporting guideline followed in each meta-analysis

# Calculate the total count for each category
reporting_guide_count <- sd %>% 
  separate_rows(reporting_standards_type, sep = ",\\s+") %>% 
  count(reporting_standards_type) %>%
  filter(reporting_standards_type != "NA") %>%
  mutate(reporting_standards_type = ifelse(n<= 2, "other", as.character(reporting_standards_type))) %>% 
    group_by(reporting_standards_type) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
reporting_guide_pct <- reporting_guide_count %>%
  mutate(proportion = n / sum(reporting_guide_count$n),
         percentage = proportion * 100)

# Create the count plot
reporting_guide_count %>%
  ggplot(aes(x = n, y = reorder(reporting_standards_type, n), fill = "#007030")) +
  geom_bar(stat = "identity", width = 0.3 , alpha = 0.7) +
  geom_text(data = reporting_guide_pct, aes(label = paste0("(", round(percentage, 0), "%)")), 
            position = position_dodge(width = 0.9), hjust = -0.7, size = 3, color = "black", fontface = "bold") +
  geom_text(aes(label = n, x = n, y = reorder(reporting_standards_type, n)), vjust = 0.5, hjust = -0.2, size = 4, color = "black") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", limits = c(0, 80)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
reporting_standards_alluvial <- sd %>% 
    separate_rows(reporting_standards_type, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>%
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    group_by(Journal_Citation_Report_Category, reporting_standards_type) %>% 
    count(reporting_standards_type, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(reporting_standards_type) %>% 
    filter(sum(freq) > 2)  # filtered for scientific databases  with more than two occurrences 


# Create the Alluvial plot
ggplot(reporting_standards_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = reporting_standards_type)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Reporting Standards Type"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Objective 3 - To investigate current reporting practices in existing meta-analyses examining the impacts of organochlorine pesticides.

Summary plot for CEESAT data

CEESAT results are presented as a percentage of result per question

# Start the data manipulation
percent_ceesat_score <- sd %>%
  filter(!is.na(author_year)) %>%
  select(studies = author_year, starts_with("CEE")) %>%
  na.omit() %>%
  pivot_longer(cols = -studies, names_to = "question", values_to = "score") %>%
  group_by(question, score) %>%
  summarise(n = n(), .groups = 'drop') %>%
  mutate(percent = (n/sum(n))*100) %>%
  mutate(across(c(question, score), as.factor)) %>%
  mutate(question = factor(question, levels = rev(levels(question)))) %>%
  mutate(score = factor(score, levels = levels(score)[c(4,1,3,2)]))


# Plot of CEESAT scores
ggplot(data = percent_ceesat_score, aes(x = question, y = percent, fill = score)) +
  geom_col(width = 0.7, position = "fill", color = "black") +
  coord_flip(ylim = c(0, 1)) +
  guides(fill = guide_legend(reverse = TRUE)) +
  scale_fill_manual(values = c("#FF0000","#FFD700","#008000", "#DAA520"), name = "Score:") +
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(), 
        panel.background = element_blank()) + 
  ylab("Proportion") + 
  xlab("CEESAT Question")

  • Objective 4. Bibliometrics: How is synthesized organochlorine pesticide evidence connected? We will investigate the countries and institutions that are primarily engaged in secondary research on organochlorine pesticides, and analyze the networks that exist between them. By doing so, we hope to gain insights into the collaborative relationships between different institutions and identify any patterns or trends in the distribution of research efforts.
fig5a <- biblioAnalysis(bib_sco)
plot(fig5a)

## fig5b - co-occurance matrix

NetMatrix_keywords <- biblioNetwork(bib_sco, analysis = "co-occurrences", network = "keywords", sep = ";")
fig5b <- networkPlot(NetMatrix_keywords, normalize="association", n = 10, 
                     Title = "Keyword Co-occurrences", type = "fruchterman", 
                     size.cex = TRUE, size = 10, remove.multiple = F, 
                     edgesize = 4, labelsize = 3, label.cex = TRUE, 
                     edges.min = 2, label.n = 9, alpha = 0.3) 

fig5c - thematic map based on keywords

par(mfrow=c(1,1), mar=c(0,2,0,2))
fig5c <- thematicMap(bib_sco, field = "ID", n = 2000, minfreq = 5, stemming = FALSE, size = 0.5, n.labels = 1, repel = TRUE)
plot(fig5c$map)

fig 5d - author collaboration network

NetMatrix_authors <- biblioNetwork(bib_sco, analysis = "collaboration",  network = "authors", sep = ";")
fig5d <- networkPlot(NetMatrix_authors,  n = 100, 
                                      Title = "Author collaboration", 
                                      type = "auto", size = 4, size.cex = TRUE, 
                                      edgesize = 10, labelsize = 1.1)

fig5e - country publications map

bibmap <- metaTagExtraction(bib_sco, Field = "AU1_CO", sep = ";") 
bibmap <- metaTagExtraction(bibmap, Field = "AU_CO", sep = ";") 
#save counts in a data frame
firstcountrycounts <- bibmap %>% 
  group_by(AU1_CO) %>%
  count() %>% 
  filter(!is.na(AU1_CO))  
#load map data
world_map <- map_data("world") %>% 
  filter(! long > 180) #remove countries with longitude >180 to make equal projection-like map without artifacts
# Format country names to match regions on the world map
firstcountrycounts$region <- str_to_title(firstcountrycounts$AU1_CO)
firstcountrycounts$region[firstcountrycounts$region == "Usa"] <- "USA" #Fix "Usa" to "USA" :
firstcountrycounts$region[firstcountrycounts$region == "United Kingdom"] <- "UK" #fix to "UK"
#(firstcountrycounts$region) %in% world_map$region #check matching
## colour all regions on the map:
emptymap <- tibble(region = unique(world_map$region), n = rep(0,length(unique(world_map$region)))) #create table with all counts as 0
fullmap <- left_join(emptymap, firstcountrycounts, by = "region") #join with actual counts table
fullmap$n <- fullmap$n.x + fullmap$n.y # make new column for fixed counts
fullmap$n[is.na(fullmap$n)] <- 0 #change NA to 0 for regions with no counts
fig5e <- fullmap %>% 
  ggplot(aes(fill = n, map_id = region)) +
  geom_map(map = world_map, color = "black") +
  expand_limits(x = world_map$long, y = world_map$lat) +
  coord_map("moll") +
  theme(legend.position="right") +
  scale_fill_gradient(low = "#98FB98", high = "#006400",
                    name = "Score", na.value = "gray70",
 limits = c(1, 20),
      guide = guide_colorbar(direction = "vertical.")) +
  guides(fill = guide_colourbar(barwidth = unit(15, units = "mm"), barheight = unit(20, units = "mm")))
fig5e

Map of europe

fig5f <- fullmap %>% 
  ggplot(aes(fill = n, map_id = region)) +
  geom_map(map = world_map, color = "black") +
  coord_map("moll", ylim = c(30, 75), xlim = c(-25, 45)) + # set limits for Europe
  theme(legend.position = "right") +
  scale_fill_gradient(low = "#98FB98", high = "#006400",
                      name = "Score", na.value = "gray70",
                      limits = c(1, 10),
                      guide = guide_colorbar(direction = "vertical.")) +
  guides(fill = guide_colourbar(barwidth = unit(15, units = "mm"), barheight = unit(20, units = "mm")))

fig5f

fig5f - country collaboration network circle plot

# Extract countries from the affiliations
bib_sco2 <- metaTagExtraction(bib_sco, Field = "AU_CO", sep = ";")

# Create a network matrix of collaborations between countries
NetMatrix_country <- biblioNetwork(bib_sco2, analysis = "collaboration", network = "countries", sep = ";")

# Convert the network matrix to a standard matrix
NetMatrix_country <- as.matrix(NetMatrix_country)

# Remove the lower triangle (as this is duplication of info)
NetMatrix_country[lower.tri(NetMatrix_country)] <- 0 

# Change column and row names to title case
colnames(NetMatrix_country) <- str_to_title(colnames(NetMatrix_country))
rownames(NetMatrix_country) <- str_to_title(rownames(NetMatrix_country))

# Change "Usa" to "USA"
colnames(NetMatrix_country)[colnames(NetMatrix_country) == "Usa"] <- "USA"
rownames(NetMatrix_country)[rownames(NetMatrix_country) == "Usa"] <- "USA"

# Change "United Kingdom" to "UK" for easier plotting
colnames(NetMatrix_country)[colnames(NetMatrix_country) == "United Kingdom"] <- "UK"
rownames(NetMatrix_country)[rownames(NetMatrix_country) == "United Kingdom"] <- "UK"

# Define colors for each country
my.cols2 <- c(
  USA = "#377eb8",
  Spain = "#ffff33",
  China = "#e41a1c",
  France = "#999999",
  Canada = "#a6cee3",
  Denmark = "#b2df8a",
  Netherlands = "#377eb8",
  Belgium = "#984ea3",
  UK = "#ffff33",
  Australia = "#4daf4a",
  Brazil = "#4daf4a",
  Germany = "#b2df8a",
  Greece = "#f781bf",
  Korea = "#f781bf",
  Ireland = "#a65628",
  Norway = "#ff7f00",
  Sweden = "#4daf4a",
  Egypt = "#f781bf",
  Italy = "#e41a1c",
  Japan = "#1f78b4",
  Switzerland = "#984ea3",
  Turkey = "#33a02c",
  Austria = "#b2df8a",
  Israel = "#f781bf",
  NewZealand = "#4daf4a",
  Russia = "#999999",
  Singapore = "#b2df8a",
  Portugal = "#984ea3",
  Finland = "#b2df8a",
  Mexico = "#a65628",
  Poland = "#b2df8a",
  SouthAfrica = "#f781bf",
  Argentina = "#ff7f00",
  Chile = "#ff7f00",
  CzechRepublic = "#b2df8a",
  Iceland = "#b2df8a",
  Peru = "#ff7f00",
  Romania = "#fb9a99",
  Serbia = "#fb9a99",
  UAE = "#a65628"
)


# Create a chord diagram of the network matrix
fig5f <- chordDiagram(NetMatrix_country, annotationTrack = "grid", preAllocateTracks = 1, grid.col = my.cols2)

# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + .1, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.5, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

fig5g collaboration matrix with self citation removed

diag(NetMatrix_country) <- 0

# Create a chord diagram of the network matrix
fig5g <- chordDiagram(NetMatrix_country, annotationTrack = "grid", preAllocateTracks = 1, grid.col = my.cols2)

# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + .1, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

fig 5h contitnent collaboration

NetMatrix_continent <- NetMatrix_country
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "USA"] <- "North America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "USA"] <- "North America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Spain"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Spain"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "China"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "China"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "France"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "France"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Canada"] <- "North America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Canada"] <- "North America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Denmark"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Denmark"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Netherlands"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Netherlands"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Belgium"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Belgium"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "UK"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "UK"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Australia"] <- "Australia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Australia"] <- "Australia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Brazil"] <- "South America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Brazil"] <- "South America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Germany"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Germany"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Finland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Finland"] <- "Europe"


colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Greece"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Greece"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Korea"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Korea"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Norway"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Norway"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Sweden"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Sweden"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Egypt"] <- "Africa"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Egypt"] <- "Africa"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Italy"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Italy"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Japan"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Japan"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Portugal"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Portugal"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Switzerland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Switzerland"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Turkey"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Turkey"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "India"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "India"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Iran"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Iran"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Costa Rica"] <- "North America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Costa Rica"] <- "North America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Czech Republic"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Czech Republic"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Hong Kong"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Hong Kong"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Iceland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Iceland"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Ireland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Ireland"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Mexico"] <- "North America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Mexico"] <- "North America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Romania"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Romania"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Slovakia"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Slovakia"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Ukraine"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Ukraine"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Australia"] <- "Oceania"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Australia"] <- "Oceania"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Kazakhstan"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Kazakhstan"] <- "Asia"


# collapsing
merge_matrix <- t(rowsum(t(NetMatrix_continent), group = colnames(NetMatrix_continent), na.rm = T))
merge_matrix2 <- rowsum(merge_matrix, group = rownames(merge_matrix))
# remove diagonal elements
diag(merge_matrix2) <- 0
# chord plot
chordDiagramFromMatrix(merge_matrix2)

# Define colors for each continent
my.cols2 <- c(
  Africa = "#CC79A7",
  NorthAmerica = "#F0E442",
  Asia = "#0072B2",
  Europe = "#E69F00",
  Oceania = "#009E73",
  SouthAmerica = "#D55E00"
)


# Create a chord diagram of the network matrix
fig5h <- chordDiagram(merge_matrix2, annotationTrack = "grid", preAllocateTracks = 1)
# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + 0.2, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

CR <- citations(bib_sco, field = "article", sep = ";") #list of most cited articles
 cbind(CR$Cited[1:10]) #ten most cited articles
##                                                                                                                                                                         [,1]
## DERSIMONIAN, R., LAIRD, N., META-ANALYSIS IN CLINICAL TRIALS (1986) CONTROL CLIN TRIALS, 7, PP. 177-188                                                                    6
## HIGGINS, J.P., THOMPSON, S.G., DEEKS, J.J., ALTMAN, D.G., MEASURING INCONSISTENCY IN META-ANALYSES (2003) BMJ, 327, PP. 557-560                                            6
## BEGG, C.B., MAZUMDAR, M., OPERATING CHARACTERISTICS OF A RANK CORRELATION TEST FOR PUBLICATION BIAS (1994) BIOMETRICS, 50, PP. 1088-1101                                   5
## HIGGINS, J.P.T., THOMPSON, S.G., DEEKS, J.J., ALTMAN, D.G., MEASURING INCONSISTENCY IN META-ANALYSES (2003) BMJ, 327 (7414), PP. 557-560                                   5
## EGGER, M., DAVEY SMITH, G., SCHNEIDER, M., MINDER, C., BIAS IN META-ANALYSIS DETECTED BY A SIMPLE, GRAPHICAL TEST (1997) BMJ, 315 (7109), PP. 629-634                      4
## EGGER, M., DAVEY, S.G., SCHNEIDER, M., MINDER, C., BIAS IN META-ANALYSIS DETECTED BY A SIMPLE, GRAPHICAL TEST (1997) BMJ, 315 (7109), PP. 629-634                          4
## GREENLAND, S., QUANTITATIVE METHODS IN THE REVIEW OF EPIDEMIOLOGIC LITERATURE (1987) EPIDEMIOL REV, 9, PP. 1-30                                                            4
## HIGGINS, J.P., THOMPSON, S.G., DEEKS, J.J., ALTMAN, D.G., MEASURING INCONSISTENCY IN META-ANALYSES (2003) BMJ, 327 (7414), PP. 557-560                                     4
## PRIYADARSHI, A., KHUDER, S.A., SCHAUB, E.A., SHRIVASTAVA, S., A META-ANALYSIS OF PARKINSON'S DISEASE AND EXPOSURE TO PESTICIDES (2000) NEUROTOXICOLOGY, 21, PP. 435-440    4
## VAN MAELE-FABRY, G., WILLEMS, J.L., OCCUPATION RELATED PESTICIDE EXPOSURE AND CANCER OF THE PROSTATE: A META-ANALYSIS (2003) OCCUP ENVIRON MED, 60, PP. 634-642            4
CR <- citations(bib_sco, field = "author", sep = ";")
cbind(CR$Cited[1:10]) #ten most cited authors
##                [,1]
## BLAIR A         118
## LEE D H          69
## HOPPIN J A       61
## THOMPSON S G     52
## ZAHM S H         51
## ALTMAN D G       43
## NEEDHAM L L      41
## EGGER M          40
## GRANDJEAN P      39
## LONGNECKER M P   39
NetMatrix_coupling <- biblioNetwork(bib_sco, analysis = "coupling", network = "references", sep = "; ")
NetMatrix_coupling_plot <- networkPlot(NetMatrix_coupling, n = 20, 
                                       Title = "Paper co-citation", type = "fruchterman", size=T, 
                                       remove.multiple=FALSE, labelsize=0.8,edgesize = 5)

LS0tDQp0aXRsZTogIlNpeHR5IHllYXJzIHNpbmNlIFNpbGVudCBTcHJpbmc6IHRvd2FyZHMgYSBiYWxhbmNlZCB2aWV3IG9mIHRoZSBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGUgbGl0ZXJhdHVyZSAiDQphdXRob3I6ICJLeWxlIE1vcnJpc29uLCBDb3JhbGllIFdpbGxpYW1zLCBMb3JlbnpvIFJpY29sZmksIE1hbGdvcmF6YXRhIExhZ2lzeiwgU2hpbmljaGkgTmFrYWdhd2EiIA0KZGF0ZTogIjIwMjMtMDMtMDkiDQpvdXRwdXQ6IA0KICBybWRmb3JtYXRzOjpyb2JvYm9vazoNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdG9jX2RlcHRoOiA0DQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCmBgYHtyLCBpbmNsdWRlID0gRkFMU0V9DQpybShsaXN0ID0gbHMoKSkNCiMga25pdHIgc2V0dGluZw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBtZXNzYWdlID0gRkFMU0UsDQogIHdhcm5pbmcgPSBGQUxTRSwgDQogIGNhY2hlID0gVFJVRSwNCiAgZWNobz1UUlVFDQopDQpgYGANCg0KDQoNCg0KSW4gdGhpcyBSbWFya2Rvd24gZG9jdW1lbnQgd2UgcHJvdmlkZSB0aGUgZm9sbG93aW5nIHdvcmtmbG93OiAgIA0KDQotIE9iamVjdGl2ZSAwLiBUbyBpbnZlc3RpZ2F0ZSBjdXJyZW50IGxpdGVyYXR1cmUgY2hhcmFjdGVyaXN0aWNzIHN1Y2ggYXMgdGltZSB0cmVuZA0KDQotIE9iamVjdGl2ZSAxIC4gVG8gZXhwbG9yZSB0aGUgdmFyaW91cyBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMgbGl0ZXJhdHVyZSBzdWNoIGFzIHRoZSBwZXN0aWNpZGVzIHVzZWQsIHRoZSBpbXBhY3RzIGVsaWNpdGVkIGluIHJlc3BvbnNlIGFuZCB0aGUgc3ViamVjdHMgdGhhdCB3ZXJlIGludmVzdGlnYXRlZC4gDQoNCi0gT2JqZWN0aXZlIDIuIFRvIGludmVzdGlnYXRlIGN1cnJlbnQgbWV0aG9kb2xvZ2ljYWwgcHJhY3RpY2VzIHdpdGhpbiBtZXRhLWFuYWx5c2lzIGludmVzdGlnYXRpbmcgdGhlIGltcGFjdHMgb2Ygb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcy4gV2Ugd2lsbCBpbnZlc3RpZ2F0ZSBob3cgdGhleSBjdXJyZW50bHkgc2VhcmNoIGZvciBleGlzdGluZyBsaXRlcmF0dXJlLCB3aGljaCBlZmZlY3Qgc2l6ZXMgYXJlIHVzZWQsIGhvdyB0aGV5IGFkanVzdCBmb3IgaGV0ZXJvZ2VuZWl0eSBhbmQgaG93IHRoZXkgYWNjb3VudCBmb3IgcmlzayBvZiBiaWFzLiANCiANCiAtIE9iamVjdGl2ZSAzIC0gVG8gaW52ZXN0aWdhdGUgY3VycmVudCByZXBvcnRpbmcgcHJhY3RpY2VzIGluIGV4aXN0aW5nIG1ldGEtYW5hbHlzZXMgZXhhbWluaW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuDQogDQogLSBPYmplY3RpdmUgNCAtIFRvIGludmVzdGlnYXRlIHRoZSByZXNlYXJjaCBvdXRwdXRzIGFjcm9zcyBkaWZmZXJlbnQgY291bnRyaWVzIGFuZCBjb250aW5lbnRzIGFuZCBpbnZlc3RpZ2F0ZSB0aGUgZGVncmVlIG9mIGNyb3NzLWNvdW50cnkgY29sbGFib3JhdGlvbi4NCiANCg0KIyAqKkxvYWQgcGFja2FnZXMgYW5kIGRhdGEqKg0KDQojIyBMb2FkIFBhY2thZ2VzIA0KDQpgYGB7ciwgcmVzdWx0cz0iaGlkZSJ9DQpybShsaXN0ID0gbHMoKSkNCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSwNCmhyYnJ0aGVtZXMsIA0KcGF0Y2h3b3JrLA0KaGVyZSwNCnN0cmluZ3IsDQprbml0ciwNCmZvcm1hdFIsDQpmb3JjYXRzLA0KZ2dwbG90MiwNCmJpYmxpb21ldHJpeCwNCmlncmFwaCwNCnN0cmluZ2ksDQpzdHJpbmdkaXN0LA0KY2lyY2xpemUsDQpnZ2FsbHV2aWFsKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSkNCg0KYGBgDQoNCg0KIyMgTG9hZCBkYXRhDQoNCk1hbnVhbGx5IGV4dHJhY3RlZCBwaWxvdCBkYXRhIGlzIHN0b3JlZCBpbiBmaXZlIHNlcGFyYXRlICoqLmNzdioqIGZpbGVzIHJlcHJlc2VudGluZyBkaWZmZXJlbnQgYXNwZWN0cyBvZiB0aGUgZGF0YSAoZXh0cmFjdGVkIHZpYSBzdHJ1Y3R1cmVkIHByZWRlZmluZWQgR29vZ2xlIEZvcm1zIC0gb25lIHBlciB0YWJsZSkuIA0KDQpCaWJsaW9ncmFwaGljIGRhdGEgcmVjb3JkcyBhcmUgZXhwb3J0ZWQgZnJvbSBTY29wdXMgKGluY2x1ZGluZyBjaXRlZCByZWZlcmVuY2VzIGZpZWxkKSBpbiAuYmliIGZvcm1hdCBhbmQgbG9jYWxseSBzYXZlZCBhcyAqKnNjb3B1cy5iaWIqKi4gDQoNCg0KDQpgYGB7cn0NCnNkIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCJvY3Bfc3JtX3N0dWR5X2RldGFpbHMuY3N2IiksIHNraXAgPSAwKQ0Kb2NwIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCAib2NwX3NybV9vY3BfZGV0YWlscy5jc3YiKSwgc2tpcCA9IDApDQpzdWIgPC0gcmVhZF9jc3YoaGVyZSgiZGF0YSIsICJvY3Bfc3JtX3N1YmplY3RfZGV0YWlscy5jc3YiKSwgc2tpcCA9MCkNCmltIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCAib2NwX3NybV9pbXBhY3RfZGV0YWlscy5jc3YiKSwgc2tpcCA9MCkNCnNwIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCAib2NwX3NybV9zcGVjaWVzX2RldGFpbHMuY3N2IiksIHNraXAgPTApDQpiaWJfc2NvIDwtIGNvbnZlcnQyZGYoaGVyZSgiZGF0YSIsImJpYl9zY28uYmliIiksIGRic291cmNlID0gInNjb3B1cyIsIGZvcm1hdCA9ICJiaWJ0ZXgiKQ0KYGBgDQoNCiMgT2JqZWN0aXZlIDAuIFRvIGludmVzdGlnYXRlIGN1cnJlbnQgbGl0ZXJhdHVyZSBjaGFyYWN0ZXJpc3RpY3Mgc3VjaCBhcyB0aW1lIHRyZW5kDQoNCiMjIEZpZ3VyZSAxIC0gVGltZSB0cmVuZHMgb2YgbnVtYmVyIG9mIG1ldGEtYW5hbHlzaXMNCmBgYHtyfQ0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uDQojIENvdW50IHRoZSBudW1iZXIgb2YgcHVibGljYXRpb25zIHBlciB5ZWFyIGFuZCBjYWxjdWxhdGUgY3VtdWxhdGl2ZSBzdW0NCnNkMSA8LSBzZCAlPiUNCiAgY291bnQocHVibGljYXRpb25feWVhcikgJT4lDQogIG11dGF0ZShuX2N1bXVsYXRpdmUgPSBjdW1zdW0obikpDQoNCiMgQW5udWFsIENvdW50IFBsb3QNCmZpZ3MxYSA8LSBzZDEgJT4lDQogIGdncGxvdChhZXMoeCA9IHB1YmxpY2F0aW9uX3llYXIsIHkgPSBuKSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiNBNjU0NzUiLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjYpLCBmb250ZmFjZSA9ICJib2xkIiwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gMywgaGp1c3QgPSAwLjQpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcShtaW4oc2QxJHB1YmxpY2F0aW9uX3llYXIpLCBtYXgoc2QxJHB1YmxpY2F0aW9uX3llYXIpLCBieSA9IDEpKSArDQogIHNjYWxlX3lfY29udGludW91cygiQW5udWFsIEFydGljbGUgQ291bnQiLCBsaW1pdHMgPSBjKDAsMTUpKSArDQogIGxhYnMoeCA9ICJZZWFyIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIGxpbmV0eXBlID0gImRhc2hlZCIpLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKHNpemUgPSAxLjIpLA0KICAgICAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfbGluZShzaXplID0gMS4yKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHNpemUgPSAxMCwgY29sb3IgPSAiIzY2NjY2NiIpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG9yID0gIiM2NjY2NjYiKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksDQogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGhqdXN0ID0gMCkpIA0KDQojIEN1bXVsYXRpdmUgQ291bnQgUGxvdA0KZmlnczFiIDwtIHNkMSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHVibGljYXRpb25feWVhciwgeSA9IG5fY3VtdWxhdGl2ZSkpICsNCiAgZ2VvbV9saW5lKGNvbG9yID0gIiM1NEE3NkEiLCBzaXplID0gMSwgbGluZXR5cGUgPSAic29saWQiKSArDQogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDMsIGZpbGwgPSAiIzU0QTc2QSIsIHN0cm9rZSA9IDApICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5fY3VtdWxhdGl2ZSksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAxLCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEobWluKHNkMSRwdWJsaWNhdGlvbl95ZWFyKSwgbWF4KHNkMSRwdWJsaWNhdGlvbl95ZWFyKSwgYnkgPSAxKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIkN1bXVsYXRpdmUgQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwxMjApKSArDQogIGxhYnMoeCA9ICJZZWFyIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIGxpbmV0eXBlID0gImRhc2hlZCIpLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKHNpemUgPSAxLjIpLA0KICAgICAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfbGluZShzaXplID0gMS4yKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHNpemUgPSAxMCwgY29sb3IgPSAiIzY2NjY2NiIpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG9yID0gIiM2NjY2NjYiKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksDQogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGhqdXN0ID0gMCkpIA0KDQojIENvbWJpbmUgdGhlIHR3byBwbG90cw0KZmlnczEgPC0gZmlnczFhIC8gZmlnczFiDQoNCmZpZ3MxDQoNCmBgYA0KDQoNCg0KIyMgRmlndXJlIHggLSBUb3RhbCBudW1iZXIgb2YgbWV0YS1hbmFseXNpcyBwZXIgc3ViamVjdCANCmBgYHtyfQ0KIyBKb2luIHRoZSBzdHVkeSBhbmQgc3ViamVjdCBkYXRhc2V0cw0Kc2Rfc3ViIDwtIGxlZnRfam9pbihzZCwgc3ViLCBieSA9ICJzdHVkeV9pZCIpDQoNCiMgQ3JlYXRlIHRoZSBhbm51YWwgY291bnQgcGxvdA0KZmlnMWEgPC0gc2Rfc3ViICU+JQ0KICBtdXRhdGUoc3ViamVjdHMgPSBzdHJzcGxpdChzdWJqZWN0LCAiLFxccysiKSkgJT4lDQogIHVubmVzdChzdWJqZWN0cykgJT4lDQogIGNvdW50KHB1YmxpY2F0aW9uX3llYXIsIHN1YmplY3RzKSAlPiUNCiAgZ3JvdXBfYnkoc3ViamVjdHMgPSByZW9yZGVyKHN1YmplY3RzLCBuKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGFzLmZhY3RvcihwdWJsaWNhdGlvbl95ZWFyKSwgeSA9IG4sIGZpbGwgPSBzdWJqZWN0cykpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gInN0YWNrIiwgYWxwaGEgPSAwLjcpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJBbm51YWwgQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwxNSkpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicyh4ID0gIlllYXIiLCB5ID0gIkFydGljbGUgQ291bnQiKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5IiwgbGluZXR5cGUgPSAiZGFzaGVkIiksDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDEuMiksDQogICAgICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9saW5lKHNpemUgPSAxLjIpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgc2l6ZSA9IDEwLCBjb2xvciA9ICIjNjY2NjY2IiksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3IgPSAiIzY2NjY2NiIpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgZmFjZSA9ICJib2xkIiksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwNCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgaGp1c3QgPSAwKSkgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKw0KICBsYWJzKGZpbGwgPSAiU3ViamVjdCBDYXRlZ29yeSIpICsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTMpKSkNCg0KIyBDcmVhdGUgdGhlIGN1bXVsYXRpdmUgY291bnQgcGxvdA0KZmlnMWIgPC0gIHNkX3N1YiAlPiUNCiAgbXV0YXRlKHN1YmplY3RzID0gc3Ryc3BsaXQoc3ViamVjdCwgIixcXHMrIikpICU+JQ0KICB1bm5lc3Qoc3ViamVjdHMpICU+JQ0KICBjb3VudChwdWJsaWNhdGlvbl95ZWFyLCBzdWJqZWN0cykgJT4lDQogIGdyb3VwX2J5KHN1YmplY3RzID0gcmVvcmRlcihzdWJqZWN0cywgbikpICU+JQ0KICBtdXRhdGUobl9jdW11bGF0aXZlID0gY3Vtc3VtKG4pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHVibGljYXRpb25feWVhciwgeSA9IG5fY3VtdWxhdGl2ZSwgZmlsbCA9IHN1YmplY3RzKSkgKw0KICBnZW9tX2FyZWEoc2l6ZSA9IDEuMiwgYWxwaGEgPSAwLjcpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJDdW11bGF0aXZlIEFydGljbGUgQ291bnQiLCBsaW1pdHMgPSBjKDAsMTE1KSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihzZF9zdWIkcHVibGljYXRpb25feWVhciksIG1heChzZF9zdWIkcHVibGljYXRpb25feWVhciksIGJ5ID0gMSkpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicyh4ID0gIlllYXIiLCB5ID0gIkN1bXVsYXRpdmUgQXJ0aWNsZSBDb3VudCIpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShzaXplID0gMS4yKSwNCiAgICAgICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDEuMiksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCBzaXplID0gMTAsIGNvbG9yID0gIiM2NjY2NjYiKSwNCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvciA9ICIjNjY2NjY2IiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLA0KICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBoanVzdCA9IDApKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArDQogIGxhYnMoZmlsbCA9ICJTdWJqZWN0IikgKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKQ0KDQojIENvbWJpbmUgdGhlIHR3byBwbG90cw0KZmlnMSA8LSBmaWcxYSAvICBmaWcxYg0KDQpmaWcxDQoNCmBgYA0KDQoNCiMgT2JqZWN0aXZlIDEuIFRvIGNoYXJhY3RlcmlzZSB0aGUgb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcyBsaXRlcmF0dXJlIHN1Y2ggYXMgdGhlIHBlc3RpY2lkZXMgdXNlZCwgdGhlIGltcGFjdHMgZWxpY2l0ZWQgaW4gcmVzcG9uc2UgYW5kIHRoZSBzdWJqZWN0cyB0aGF0IHdlcmUgaW52ZXN0aWdhdGVkLiANCg0KIyMgRmlndXJlIHggLSBUb3RhbCBjb3VudCBvZiBlYWNoIG9yZ2Fub2NobG9yaW5lIHVzZWQgaW4gbWV0YS1hbmFseXNpcw0KDQpgYGB7cn0NCiMgVHJhbnNmb3JtIHRoZSBkYXRhIA0Kb2NwX2NvdW50IDwtDQogIG9jcCAlPiUgDQogIHNlcGFyYXRlX3Jvd3Mob2NwLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KG9jcCkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKG9jcCkpICU+JSAjIGZpbHRlciBvdXQgTkEgDQogZmlsdGVyKG9jcCAhPSAibm90IHJlcG9ydGVkIikgJT4lIA0KICBhcnJhbmdlKGRlc2MobikpICU+JSANCiAgbXV0YXRlKG9jcCA9IGlmZWxzZShuIDw9IDMsICJvdGhlciIsIGFzLmNoYXJhY3RlcihvY3ApKSkgJT4lICAjIyBJIE5FRUQgVE8gTElTVCBBTEwgVEhFIE9USEVSUyBIRVJFIFdJVEggVEhFSVIgQ09VTlRTDQogIGdyb3VwX2J5KG9jcCkgJT4lIA0KICBzdW1tYXJpc2UobiA9c3VtKG4pKQ0KDQpvY3BfcGN0IDwtIG9jcF9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bShvY3BfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90IA0Kb2NwX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihvY3AsIG4pLCBmaWxsID0gIiMwMDcwMzAiKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjYsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChkYXRhID0gb2NwX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMCksICIlKSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgaGp1c3QgPSAtMC45LCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gKyAwLjUsIHkgPSByZW9yZGVyKG9jcCwgbikpLCB2anVzdCA9IDAuNSwgaGp1c3QgPSAwLCBzaXplID0gNCwgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgNDUpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICAgICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgICAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQogDQpgYGANCg0KIyMgRmlndXJlIHggLSBUb3RhbCBwcm9wb3J0aW9uIG9mIG1ldGEtYW5hbHlzaXMgcGVyIHN1YmplY3QgDQpub3RlOiBzb21lIG1ldGEtYW5hbHlzaXMgbWF5IGNvbnRyaWJ1dGUgdG8gbXVsdGlwbGUgc2VjdGlvbnMgaWYgaW52b2x2ZSBtdWx0aXBsZSBzdWJqZWN0cyANCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCnN1YmplY3RfY291bnQgPC0gDQogIHN1YiAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhzdWJqZWN0LCBzZXAgPSAiLFxccysiKSAlPiUgDQogICAgY291bnQoc3ViamVjdCkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0Kc3ViamVjdF9wY3QgPC0gc3ViamVjdF9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bShzdWJqZWN0X2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24qMTAwKQ0KDQojIENyZWF0ZSB0aGUgY291bnQgcGxvdA0Kc3ViamVjdF9jb3VudCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIoc3ViamVjdCwgbiksIGZpbGwgPSAiIzAwNzAzMCIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuMyAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChkYXRhID0gc3ViamVjdF9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDApLCAiJSkiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIGhqdXN0ID0gLTAuNywgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuICsgMC41LCB5ID0gcmVvcmRlcihzdWJqZWN0LCBuKSksIHZqdXN0ID0gMC41LCBoanVzdCA9IDAsIHNpemUgPSA0LCBjb2xvciA9ICJibGFjayIpICsNCiAgc2NhbGVfZmlsbF9pZGVudGl0eShndWlkZSA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBcnRpY2xlIENvdW50IiwgZXhwYW5kID0gYygwLCAwKSwgbGltaXRzID0gYygwLCA5MCkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgICAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5Iiwgc2l6ZSA9IDAuNSksDQogICAgICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KYGBgDQoNCg0KYGBge3J9DQojIENhbGN1bGF0ZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0KaW1wYWN0X2NvdW50IDwtIA0KICBpbSAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhpbXBhY3QsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgICBjb3VudChpbXBhY3QpICU+JSANCiAgZmlsdGVyKGltcGFjdCAhPSAiTkEiKSAlPiUNCiAgbXV0YXRlKGltcGFjdCA9IGlmZWxzZShuPD0gMSwgIm90aGVyIiwgYXMuY2hhcmFjdGVyKGltcGFjdCkpKSAlPiUgDQogICAgZ3JvdXBfYnkoaW1wYWN0KSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmltcGFjdF9wY3QgPC0gaW1wYWN0X2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKGltcGFjdF9jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uKjEwMCkNCg0KIyBHZW5lcmF0ZSBhIGdyYXBoDQppbXBhY3RfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKGltcGFjdCwgbiksIGZpbGwgPSAiIzAwNzAzMCIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuMyAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChkYXRhID0gaW1wYWN0X3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMSksICIlKSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgaGp1c3QgPSAtMC43LCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4sIHkgPSByZW9yZGVyKGltcGFjdCwgbikpLCB2anVzdCA9IDAuNSwgaGp1c3QgPSAtMC4yLCBzaXplID0gNCwgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwgbWF4KGltcGFjdF9jb3VudCRuKSoxLjIpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBzaXplID0gMC41KSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQoNCmBgYA0KDQojIyBBbGx1dmlhbCBwbG90IG9mIG9jcCwgc3ViamVjdHkgYW5kIGltcGFjdCANCmBgYHtyfQ0KDQojIFRyYW5zZm9ybSB0aGUgZGF0YSANCmRmIDwtIGltICU+JQ0KICBsZWZ0X2pvaW4ob2NwLCBieSA9ICJzdHVkeV9pZCIpICU+JQ0KICBsZWZ0X2pvaW4oc3ViLCBieSA9ICJzdHVkeV9pZCIpICU+JQ0KICBzZXBhcmF0ZV9yb3dzKHN1YmplY3QsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgc2VwYXJhdGVfcm93cyhvY3AsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgc2VwYXJhdGVfcm93cyhpbXBhY3QsIHNlcCA9ICIsXFxzKyIpICU+JQ0KICBtdXRhdGUob2NwX2NvbnZlcnQgPSBjYXNlX3doZW4oICMgUmVuYW1lIGlzb21lcnMgYW5kIG1ldGFib2xpdGVzIHRvIHBhcmVudCBjaGVtaWNhbCAoYmVzaWRlcyBERFQsIERERCBhbmQgRERFIHdoaWNoIGFyZSBqdXN0IGlzb21lcnMpDQogICAgZ3JlcGwoIkREVCIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJERFQiLCANCiAgICBncmVwbCgiREREIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkRERCIsIA0KICAgIGdyZXBsKCJEREUiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiRERFIiwgDQogICAgZ3JlcGwoIkhDSHxIZXhhY2hsb3JvfEJIQ3xMaW5kYW5lIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkhleGFjaGxvcm9oZXhhbmUiLCANCiAgICBncmVwbCgiQ2hsb3JkYW5lIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkNobG9yZGFuZSIsICANCiAgICBncmVwbCgiRW5kb3N1bGZhbiIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJFbmRvc3VsZmFuIiwgDQogICAgZ3JlcGwoIk5vbmFjaGxvciIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJOb25hY2hsb3JlIiwgDQogICAgZ3JlcGwoIkhlcHRhY2hsb3IiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiSGVwdGFjaGxvciIsDQogICAgZ3JlcGwoIlRDREQiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiVENERCIsIA0KICAgIGdyZXBsKCJFbmRyaW4iLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiRW5kcmluIiwNCiAgICBUUlVFIH4gb2NwKSkgJT4lDQogIGZpbHRlcighZ3JlcGwoIm5vdCByZXBvcnRlZCIsIG9jcF9jb252ZXJ0LCBpZ25vcmUuY2FzZSA9IFRSVUUpKSAlPiUNCiAgZ3JvdXBfYnkob2NwX2NvbnZlcnQsIHN1YmplY3QsIGltcGFjdCkgJT4lDQogIHN1bW1hcmlzZShmcmVxID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUNCiAgZ3JvdXBfYnkob2NwX2NvbnZlcnQpICU+JQ0KICBmaWx0ZXIoc3VtKGZyZXEpID4gMikgJT4lICMgZmlsdGVyZWQgZm9yIG9jcCdzIHdpdGggbW9yZSB0aGFuIHR3byBvY2N1cnJlbmNlcyANCiAgZ3JvdXBfYnkoaW1wYWN0KSAlPiUgDQogIGZpbHRlcihzdW0oZnJlcSkgPiAzKSAlPiUgIyBmaWx0ZXIgZm9yIGltcGFjdHMgd2l0aCBtb3JlIHRoYW4gdGhyZWUgb2NjdXJyZW5jZXMgDQogIG11dGF0ZShzdWJqZWN0ID0gZmFjdG9yKHN1YmplY3QsIGxldmVscyA9IGMoImVudmlyb25tZW50IiwgIm5vbi1odW1hbiBhbmltYWwiLCAiaHVtYW4iKSwgb3JkZXJlZCA9IFRSVUUpKQ0KDQoNCiMgUGxvdCBhbGx1dmlhbCBwbG90IGJldHdlZW4gb2NwLCBzdWJqZWN0IGFuZCBpbXBhY3QgDQpnZ3Bsb3QoZGF0YSA9IGRmLA0KICAgICAgIGFlcyhheGlzMSA9IG9jcF9jb252ZXJ0LCBheGlzMiA9IHN1YmplY3QsIGF4aXMzID0gaW1wYWN0LCB5ID0gZnJlcSkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJPcmdhbm9jaGxvcmluZSBQZXN0aWNpZGUiLCAiU3ViamVjdCIsICJJbXBhY3QiKSwgZXhwYW5kID0gYyguMDUsIC4xMCkpICsNCiAgeGxhYigiVmFyaWFibGVzIikgKw0KICBnZW9tX2FsbHV2aXVtKGFlcyhmaWxsID0gc3ViamVjdCkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS8yLCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDMpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIsIG5hbWUgPSAiU3ViamVjdCBDYXRlZ29yeSIpDQpgYGANCg0KDQojIE9iamVjdGl2ZSAyLiBUbyBpbnZlc3RpZ2F0ZSBjdXJyZW50IG1ldGhvZG9sb2dpY2FsIHByYWN0aWNlcyB3aXRoaW4gbWV0YS1hbmFseXNpcyBpbnZlc3RpZ2F0aW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuIFdlIHdpbGwgaW52ZXN0aWdhdGUgaG93IHRoZXkgY3VycmVudGx5IHNlYXJjaCBmb3IgZXhpc3RpbmcgbGl0ZXJhdHVyZSwgd2hpY2ggZWZmZWN0IHNpemVzIGFyZSB1c2VkLCBob3cgdGhleSBhZGp1c3QgZm9yIGhldGVyb2dlbmVpdHkgYW5kIGhvdyB0aGV5IGFjY291bnQgZm9yIHJpc2sgb2YgYmlhcy4gDQoNCiMjIEZpZ3VyZSB4IC0gVG90YWwgY291bnQgb2YgZWFjaCBkYXRhYmFzZSB1c2VkIHRvIHNlYXJjaCB0aGUgbGl0ZXJhdHVyZSB3aXRoaW4gZWFjaCBtZXRhLWFuYWx5c2lzDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIHRoZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0KZGF0YWJhc2VfY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGRhdGFiYXNlX3NlYXJjaCwgc2VwID0gIixcXHMrIikgJT4lIA0KICBjb3VudChkYXRhYmFzZV9zZWFyY2gpICU+JSANCiAgZmlsdGVyKGRhdGFiYXNlX3NlYXJjaCAhPSAibm90IHJlcG9ydGVkIikgJT4lIA0KICBhcnJhbmdlKGRlc2MobikpICU+JSANCiAgbXV0YXRlKGRhdGFiYXNlX3NlYXJjaCA9IGlmZWxzZShuPD0gMiwgIm90aGVyIiwgYXMuY2hhcmFjdGVyKGRhdGFiYXNlX3NlYXJjaCkpKSAlPiUgDQogICAgZ3JvdXBfYnkoZGF0YWJhc2Vfc2VhcmNoKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KZGF0YWJhc2VfcGN0IDwtIGRhdGFiYXNlX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0oZGF0YWJhc2VfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCmRhdGFiYXNlX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihkYXRhYmFzZV9zZWFyY2gsIG4pLCBmaWxsID0gIiMwMDcwMzAiKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjMgLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoZGF0YSA9IGRhdGFiYXNlX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMCksICIlKSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSx2anVzdCA9IDAuNSwgaGp1c3QgPSAtMC43LCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4sIHkgPSByZW9yZGVyKGRhdGFiYXNlX3NlYXJjaCwgbikpLCB2anVzdCA9IDAuNSwgaGp1c3QgPSAtMC4xLCBzaXplID0gNCwgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwgNjApKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBzaXplID0gMC41KSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQoNCg0KYGBgDQoNCiANCmBgYHtyfQ0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uIA0KZGF0YWJhc2VfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoZGF0YWJhc2Vfc2VhcmNoLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgICBzZXBhcmF0ZV9yb3dzKEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBzZXAgPSAiL1xccysiKSAlPiUgDQogICAgZmlsdGVyKCFncmVwbCgibm8gY2F0ZWdvcnkgZm91bmQiLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgaWdub3JlLmNhc2UgPSBUUlVFKSkgJT4lIA0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBkYXRhYmFzZV9zZWFyY2gpICU+JSANCiAgICBjb3VudChkYXRhYmFzZV9zZWFyY2gsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShkYXRhYmFzZV9zZWFyY2gpICU+JSANCiAgICBmaWx0ZXIoc3VtKGZyZXEpID4gMikgICMgZmlsdGVyZWQgZm9yIHNjaWVudGljIGRhdGFiYXNlcyAgd2l0aCBtb3JlIHRoYW4gdHdvIG9jY3VycmVuY2VzIA0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZ2dwbG90KGRhdGFiYXNlX2FsbHV2aWFsLCBhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGF4aXMyID0gZGF0YWJhc2Vfc2VhcmNoKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIkRhdGFiYXNlIFNlYXJjaCIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS84LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDMpICsNCiAgdGhlbWVfbWluaW1hbCgpIA0KDQoNCg0KICANCmBgYA0KDQojIyBGaWd1cmUgeCAtIFRvdGFsIGNvdW50IG9mIGVhY2ggZWZmZWN0IHNpemUgbWVhc3VyZSB1c2VkIHdpdGhpbiBlYWNoIG1ldGEtYW5hbHlzaXMNCmBgYHtyIHBsb3QgZWZmZWN0IHNpemUgdXNlZCB9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCmVmZmVjdHNpemVfY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGVmZmVjdF9zaXplLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KGVmZmVjdF9zaXplKSAlPiUNCiAgZmlsdGVyKGVmZmVjdF9zaXplICE9ICJOQSIpICU+JQ0KICBtdXRhdGUoZWZmZWN0X3NpemUgPSBpZmVsc2Uobjw9IDIsICJvdGhlciIsIGFzLmNoYXJhY3RlcihlZmZlY3Rfc2l6ZSkpKSAlPiUgDQogICAgZ3JvdXBfYnkoZWZmZWN0X3NpemUpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KZWZmZWN0c2l6ZV9wY3QgPC0gZWZmZWN0c2l6ZV9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKGVmZmVjdHNpemVfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCmVmZmVjdHNpemVfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKGVmZmVjdF9zaXplLCBuKSwgZmlsbCA9ICIjMDA3MDMwIikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC4zICwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBlZmZlY3RzaXplX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMCksICIlKSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgaGp1c3QgPSAtMC43LCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4sIHkgPSByZW9yZGVyKGVmZmVjdF9zaXplLCBuKSksIHZqdXN0ID0gMC41LCBoanVzdCA9IC0wLjIsIHNpemUgPSA0LCBjb2xvciA9ICJibGFjayIpICsNCiAgc2NhbGVfZmlsbF9pZGVudGl0eShndWlkZSA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBcnRpY2xlIENvdW50IiwgbGltaXRzID0gYygwLCA2MCkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICkNCmBgYA0KDQpgYGB7cn0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCmVmZmVjdHNpemVfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoZWZmZWN0X3NpemUsIHNlcCA9ICIsXFxzKyIpICU+JQ0KICAgIHNlcGFyYXRlX3Jvd3MoSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIHNlcCA9ICIvXFxzKyIpICU+JSANCiAgICBmaWx0ZXIoIWdyZXBsKCJubyBjYXRlZ29yeSBmb3VuZCIsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBpZ25vcmUuY2FzZSA9IFRSVUUpKSAlPiUgDQogICAgZmlsdGVyKCFpcy5uYShlZmZlY3Rfc2l6ZSkpICU+JQ0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBlZmZlY3Rfc2l6ZSkgJT4lIA0KICAgIGNvdW50KGVmZmVjdF9zaXplLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkgJT4lIA0KICAgIHN1bW1hcmlzZShmcmVxID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUgDQogICAgZ3JvdXBfYnkoZWZmZWN0X3NpemUpICMgICU+JSANCiAgIyAgIGZpbHRlcihzdW0oZnJlcSkgPiAyKSAgIyBmaWx0ZXJlZCBmb3Igc2NpZW50aWZpYyBkYXRhYmFzZXMgIHdpdGggbW9yZSB0aGFuIHR3byBvY2N1cnJlbmNlcyANCg0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZ2dwbG90KGVmZmVjdHNpemVfYWxsdXZpYWwsIGFlcyh5ID0gZnJlcSAsYXhpczEgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgYXhpczIgPSBlZmZlY3Rfc2l6ZSkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSIsICJFZmZlY3QgU2l6ZSIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS84LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDMpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQojIyBGaWd1cmUgeCAtIFRvdGFsIGNvdW50IG9mIGVhY2ggc29mdHdhcmUgdXNlZCB0byBhbmFseXNlIHRoZSBkYXRhIHdpdGhpbiBlYWNoIG1ldGEtYW5hbHlzaXMNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQpzb2Z0d2FyZV9jb3VudCA8LSBzZCAlPiUgDQogIHNlcGFyYXRlX3Jvd3Moc29mdHdhcmVfYW5hbHlzaXMsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgY291bnQoc29mdHdhcmVfYW5hbHlzaXMpICU+JQ0KICBmaWx0ZXIoc29mdHdhcmVfYW5hbHlzaXMgIT0gIk5BIikgJT4lDQogIG11dGF0ZShzb2Z0d2FyZV9hbmFseXNpcyA9IGlmZWxzZShuPD0gMiwgIm90aGVyIiwgYXMuY2hhcmFjdGVyKHNvZnR3YXJlX2FuYWx5c2lzKSkpICU+JSANCiAgICBncm91cF9ieShzb2Z0d2FyZV9hbmFseXNpcykgJT4lDQogIHN1bW1hcmlzZShuID0gc3VtKG4pKQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQpzb2Z0d2FyZV9wY3QgPC0gc29mdHdhcmVfY291bnQgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gbiAvIHN1bShzb2Z0d2FyZV9jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uICogMTAwKQ0KDQojIENyZWF0ZSB0aGUgY291bnQgcGxvdA0Kc29mdHdhcmVfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKHNvZnR3YXJlX2FuYWx5c2lzLCBuKSwgZmlsbCA9ICIjMDA3MDMwIikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC4zICwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBzb2Z0d2FyZV9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDApLCAiJSkiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIGhqdXN0ID0gLTAuNywgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuLCB5ID0gcmVvcmRlcihzb2Z0d2FyZV9hbmFseXNpcywgbikpLCB2anVzdCA9IDAuNSwgaGp1c3QgPSAtMC4yLCBzaXplID0gNCwgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwgNjApKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBzaXplID0gMC41KSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQoNCg0KYGBgDQoNCmBgYHtyfQ0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uIA0Kc29mdHdhcmVfYW5hbHlzaXNfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3Moc29mdHdhcmVfYW5hbHlzaXMsIHNlcCA9ICIsXFxzKyIpICU+JQ0KICAgIHNlcGFyYXRlX3Jvd3MoSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIHNlcCA9ICIvXFxzKyIpICU+JSANCiAgICBmaWx0ZXIoIWdyZXBsKCJubyBjYXRlZ29yeSBmb3VuZCIsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBpZ25vcmUuY2FzZSA9IFRSVUUpKSAlPiUgDQogICAgZmlsdGVyKCFpcy5uYShzb2Z0d2FyZV9hbmFseXNpcykpICU+JQ0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBzb2Z0d2FyZV9hbmFseXNpcykgJT4lIA0KICAgIGNvdW50KHNvZnR3YXJlX2FuYWx5c2lzLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkgJT4lIA0KICAgIHN1bW1hcmlzZShmcmVxID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUgDQogICAgZ3JvdXBfYnkoc29mdHdhcmVfYW5hbHlzaXMpDQoNCg0KIyBDcmVhdGUgdGhlIEFsbHV2aWFsIHBsb3QNCmdncGxvdChzb2Z0d2FyZV9hbmFseXNpc19hbGx1dmlhbCwgYWVzKHkgPSBmcmVxICxheGlzMSA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBheGlzMiA9IHNvZnR3YXJlX2FuYWx5c2lzKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIlNvZnR3YXJlIEFuYWx5c2lzIiksIGV4cGFuZCA9IGMoLjA1LCAuMDUpKSArDQogIHhsYWIoIlZhcmlhYmxlcyIpICsNCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzgsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gMykgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSB4IC0gVG90YWwgY291bnQgb2YgZWFjaCBoZXRlcm9nZW5laXR5IHRlc3QgdXNlZCB3aXRoaW4gZWFjaCBtZXRhLWFuYWx5c2lzDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIHRoZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0KaGV0ZXJvZ2VuZWl0eV9jb3VudCA8LSBzZCAlPiUgDQogIHNlcGFyYXRlX3Jvd3MoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCwgc2VwID0gIixcXHMrIikgJT4lIA0KICBjb3VudChoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUNCiAgZmlsdGVyKGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QgIT0gIk5BIikgJT4lDQogIG11dGF0ZShoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kID0gaWZlbHNlKG48PSAyLCAib3RoZXIiLCBhcy5jaGFyYWN0ZXIoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCkpKSAlPiUgDQogICAgZ3JvdXBfYnkoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCkgJT4lDQogIHN1bW1hcmlzZShuID0gc3VtKG4pKQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQpoZXRlcm9nZW5laXR5X3BjdCA8LSBoZXRlcm9nZW5laXR5X2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0oaGV0ZXJvZ2VuZWl0eV9jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uICogMTAwKQ0KDQojIENyZWF0ZSB0aGUgY291bnQgcGxvdA0KaGV0ZXJvZ2VuZWl0eV9jb3VudCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCwgbiksIGZpbGwgPSAiIzAwNzAzMCIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuMyAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChkYXRhID0gaGV0ZXJvZ2VuZWl0eV9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDApLCAiJSkiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIGhqdXN0ID0gLTAuNywgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuLCB5ID0gcmVvcmRlcihoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kLCBuKSksIHZqdXN0ID0gMC41LCBoanVzdCA9IC0wLjIsIHNpemUgPSA0LCBjb2xvciA9ICJibGFjayIpICsNCiAgc2NhbGVfZmlsbF9pZGVudGl0eShndWlkZSA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBcnRpY2xlIENvdW50IiwgbGltaXRzID0gYygwLCAxMDApKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBzaXplID0gMC41KSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQpgYGANCiANCiANCmBgYHtyfQ0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uIA0KaGV0ZXJvZ2VuZWl0eV9hbGx1dmlhbCA8LSBzZCAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgICBzZXBhcmF0ZV9yb3dzKEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBzZXAgPSAiL1xccysiKSAlPiUgDQogICAgZmlsdGVyKCFncmVwbCgibm8gY2F0ZWdvcnkgZm91bmQiLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgaWdub3JlLmNhc2UgPSBUUlVFKSkgJT4lIA0KICAgIGZpbHRlcighaXMubmEoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCkpICU+JQ0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUgDQogICAgY291bnQoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnkpICU+JSANCiAgICBzdW1tYXJpc2UoZnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIA0KICAgIGdyb3VwX2J5KGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QpICANCg0KIyBDcmVhdGUgdGhlIEFsbHV2aWFsIHBsb3QNCmdncGxvdChoZXRlcm9nZW5laXR5X2FsbHV2aWFsLCBhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGF4aXMyID0gaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSIsICJIZXRlcm9nZW5laXR5IEFzc2Vzc21lbnQgTWV0aG9kIiksIGV4cGFuZCA9IGMoLjA1LCAuMDUpKSArDQogIHhsYWIoIlZhcmlhYmxlcyIpICsNCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzgsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gMykgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQogDQojIyBGaWd1cmUgeHggLSBUb3RhbCBjb3VudCBmb3IgZWFjaCBzZW5zaXRpdml0eSBhbmFseXNpcyB1c2VkIGluIGVhY2ggbWV0YS1hbmFseXNpcw0KYGBge3J9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCnNlbnNpdGl2aXR5X2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgY291bnQoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKSAlPiUNCiAgZmlsdGVyKHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCAhPSAiTkEiKSAlPiUNCiAgbXV0YXRlKHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCA9IGlmZWxzZShuPD0gMSwgIm90aGVyIiwgYXMuY2hhcmFjdGVyKHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCkpKSAlPiUgDQogICAgZ3JvdXBfYnkoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCnNlbnNpdGl2aXR5X3BjdCA8LSBzZW5zaXRpdml0eV9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKHNlbnNpdGl2aXR5X2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpzZW5zaXRpdml0eV9jb3VudCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kLCBuKSwgZmlsbCA9ICIjMDA3MDMwIikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC4zICwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBzZW5zaXRpdml0eV9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDApLCAiJSkiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIGhqdXN0ID0gLTAuNywgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuLCB5ID0gcmVvcmRlcihzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QsIG4pKSwgdmp1c3QgPSAwLjUsIGhqdXN0ID0gLTAuMiwgc2l6ZSA9IDQsIGNvbG9yID0gImJsYWNrIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBsaW1pdHMgPSBjKDAsIDQwKSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5Iiwgc2l6ZSA9IDAuNSksDQogICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSINCiAgKQ0KDQpgYGANCg0KYGBge3J9DQojIERhdGEgVHJhbnNmb3JtYXRpb24gDQpzZW5zaXRpdml0eV9hbmFseXNpc19hbGx1dmlhbCA8LSBzZCAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QsIHNlcCA9ICIsXFxzKyIpICU+JQ0KICAgIHNlcGFyYXRlX3Jvd3MoSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIHNlcCA9ICIvXFxzKyIpICU+JSANCiAgICBmaWx0ZXIoIWdyZXBsKCJubyBjYXRlZ29yeSBmb3VuZCIsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBpZ25vcmUuY2FzZSA9IFRSVUUpKSAlPiUgDQogICAgZmlsdGVyKCFpcy5uYShzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QpKSAlPiUNCiAgICBncm91cF9ieShKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKSAlPiUgDQogICAgY291bnQoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkgJT4lIA0KICAgIHN1bW1hcmlzZShmcmVxID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUgDQogICAgZ3JvdXBfYnkoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKQ0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZ2dwbG90KHNlbnNpdGl2aXR5X2FuYWx5c2lzX2FsbHV2aWFsLCBhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGF4aXMyID0gc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIlNlbnNpdGl2aXR5IEFuYWx5c2lzIE1ldGhvZCIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS84LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDMpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQojIyBGaWd1cmUgeCAtIFRvdGFsIGNvdW50IG9mIGVhY2ggdHlwZSBvZiBiZXR3ZWVuIHN0dWR5IGJpYXMgaW52ZXN0aWFndGVkIGluIGVhY2ggbWV0YS1hbmFseXNpcw0KYGBge3J9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCmJpYXNfdHlwZV9jb3VudCA8LSBzZCAlPiUgDQogIHNlcGFyYXRlX3Jvd3MoYmlhc19hc3Nlc3NtZW50X3R5cGUsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgY291bnQoYmlhc19hc3Nlc3NtZW50X3R5cGUpICU+JQ0KICBmaWx0ZXIoYmlhc19hc3Nlc3NtZW50X3R5cGUgIT0gIk5BIikgJT4lDQogIGdyb3VwX2J5KGJpYXNfYXNzZXNzbWVudF90eXBlKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmJpYXNfdHlwZV9wY3QgPC0gYmlhc190eXBlX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0oYmlhc190eXBlX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpiaWFzX3R5cGVfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKGJpYXNfYXNzZXNzbWVudF90eXBlLCBuKSwgZmlsbCA9ICIjMDA3MDMwIikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC4zICwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBiaWFzX3R5cGVfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAwKSwgIiUpIikpLCANCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCBoanVzdCA9IC0wLjcsIHNpemUgPSAzLCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiwgeSA9IHJlb3JkZXIoYmlhc19hc3Nlc3NtZW50X3R5cGUsIG4pKSwgdmp1c3QgPSAwLjUsIGhqdXN0ID0gLTAuMiwgc2l6ZSA9IDQsIGNvbG9yID0gImJsYWNrIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBsaW1pdHMgPSBjKDAsIDc1KSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5Iiwgc2l6ZSA9IDAuNSksDQogICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSINCiAgKQ0KDQpgYGANCg0KDQpgYGB7cn0NCg0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uIA0KYmlhc19hc3Nlc3NtZW50X2FsbHV2aWFsIDwtIHNkICU+JSANCiAgICBzZXBhcmF0ZV9yb3dzKGJpYXNfYXNzZXNzbWVudF90eXBlLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgICBzZXBhcmF0ZV9yb3dzKEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBzZXAgPSAiL1xccysiKSAlPiUgDQogICAgZmlsdGVyKCFncmVwbCgibm8gY2F0ZWdvcnkgZm91bmQiLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgaWdub3JlLmNhc2UgPSBUUlVFKSkgJT4lIA0KICAgIGZpbHRlcighaXMubmEoYmlhc19hc3Nlc3NtZW50X3R5cGUpKSAlPiUNCiAgICBncm91cF9ieShKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgYmlhc19hc3Nlc3NtZW50X3R5cGUpICU+JSANCiAgICBjb3VudChiaWFzX2Fzc2Vzc21lbnRfdHlwZSwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnkpICU+JSANCiAgICBzdW1tYXJpc2UoZnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIA0KICAgIGdyb3VwX2J5KGJpYXNfYXNzZXNzbWVudF90eXBlKQ0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZ2dwbG90KGJpYXNfYXNzZXNzbWVudF9hbGx1dmlhbCwgYWVzKHkgPSBmcmVxICxheGlzMSA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBheGlzMiA9IGJpYXNfYXNzZXNzbWVudF90eXBlKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIkJpYXMgQXNzZXNzbWVudCBUeXBlIiksIGV4cGFuZCA9IGMoLjA1LCAuMDUpKSArDQogIHhsYWIoIlZhcmlhYmxlcyIpICsNCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzgsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gMykgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KDQpgYGANCg0KIyMgRmlndXJlIHggLSBUb3RhbCBjb3VudCBmb3IgZWFjaCBzdGF0aXN0aWNhbCBtZXRob2RvbG9neSB0byBpbnZlc3RpZ2F0ZSB3aXRoaW4gc3R1ZHkgYmlhcyB1c2VkIGluIGVhY2ggbWV0YS1hbmFseXNpcw0KYGBge3J9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCmJpYXNfbWV0aG9kX2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KGJpYXNfYXNzZXNzbWVudF9tZXRob2QpICU+JQ0KICBmaWx0ZXIoYmlhc19hc3Nlc3NtZW50X21ldGhvZCAhPSAiTkEiKSAlPiUNCiAgICBncm91cF9ieShiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmJpYXNfbWV0aG9kX3BjdCA8LSBiaWFzX21ldGhvZF9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKGJpYXNfbWV0aG9kX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpiaWFzX21ldGhvZF9jb3VudCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIoYmlhc19hc3Nlc3NtZW50X21ldGhvZCwgbiksIGZpbGwgPSAiIzAwNzAzMCIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuMyAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChkYXRhID0gYmlhc19tZXRob2RfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAwKSwgIiUpIikpLCANCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCBoanVzdCA9IC0wLjcsIHNpemUgPSAzLCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiwgeSA9IHJlb3JkZXIoYmlhc19hc3Nlc3NtZW50X21ldGhvZCwgbikpLCB2anVzdCA9IDAuNSwgaGp1c3QgPSAtMC4yLCBzaXplID0gNCwgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwgNzApKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBzaXplID0gMC41KSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQoNCmBgYA0KDQpgYGB7cn0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCmJpYXNfYXNzZXNzbWVudF9hbGx1dmlhbCA8LSBzZCAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgICBzZXBhcmF0ZV9yb3dzKEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBzZXAgPSAiL1xccysiKSAlPiUgDQogICAgZmlsdGVyKCFncmVwbCgibm8gY2F0ZWdvcnkgZm91bmQiLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgaWdub3JlLmNhc2UgPSBUUlVFKSkgJT4lIA0KICAgIGZpbHRlcighaXMubmEoYmlhc19hc3Nlc3NtZW50X21ldGhvZCkpICU+JQ0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUgDQogICAgY291bnQoYmlhc19hc3Nlc3NtZW50X21ldGhvZCwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnkpICU+JSANCiAgICBzdW1tYXJpc2UoZnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIA0KICAgIGdyb3VwX2J5KGJpYXNfYXNzZXNzbWVudF9tZXRob2QpDQoNCiMgQ3JlYXRlIHRoZSBBbGx1dmlhbCBwbG90DQpnZ3Bsb3QoYmlhc19hc3Nlc3NtZW50X2FsbHV2aWFsLCBhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGF4aXMyID0gYmlhc19hc3Nlc3NtZW50X21ldGhvZCkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSIsICJCaWFzIEFzc2Vzc21lbnQgTWV0aG9kIiksIGV4cGFuZCA9IGMoLjA1LCAuMDUpKSArDQogIHhsYWIoIlZhcmlhYmxlcyIpICsNCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzgsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gMykgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQpyb2JfbWV0aG9kX2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhyb2JfYXNzZXNzbWVudF9tZXRob2QsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgY291bnQocm9iX2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUNCiAgZmlsdGVyKHJvYl9hc3Nlc3NtZW50X21ldGhvZCAhPSAiTkEiKSAlPiUNCiAgZ3JvdXBfYnkocm9iX2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCnJvYl9tZXRob2RfcGN0IDwtIHJvYl9tZXRob2RfY291bnQgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gbiAvIHN1bShyb2JfbWV0aG9kX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpyb2JfbWV0aG9kX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihyb2JfYXNzZXNzbWVudF9tZXRob2QsIG4pLCBmaWxsID0gIiMwMDcwMzAiKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjMgLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoZGF0YSA9IHJvYl9tZXRob2RfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAwKSwgIiUpIikpLCANCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCBoanVzdCA9IC0wLjcsIHNpemUgPSAzLCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiwgeSA9IHJlb3JkZXIocm9iX2Fzc2Vzc21lbnRfbWV0aG9kLCBuKSksIHZqdXN0ID0gMC41LCBoanVzdCA9IC0wLjIsIHNpemUgPSA0LCBjb2xvciA9ICJibGFjayIpICsNCiAgc2NhbGVfZmlsbF9pZGVudGl0eShndWlkZSA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBcnRpY2xlIENvdW50IiwgbGltaXRzID0gYygwLCA3MCkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICkNCg0KYGBgDQoNCmBgYHtyfQ0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uIA0Kcm9ibWV0aG9kX2FsbHV2aWFsIDwtIHNkICU+JSANCiAgICBzZXBhcmF0ZV9yb3dzKHJvYl9hc3Nlc3NtZW50X21ldGhvZCwgc2VwID0gIixcXHMrIikgJT4lDQogICAjIGZpbHRlcighaXMubmEocm9iX2Fzc2Vzc21lbnRfbWV0aG9kKSkgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgc2VwID0gIi9cXHMrIikgJT4lDQogICAgZmlsdGVyKCFncmVwbCgibm8gY2F0ZWdvcnkgZm91bmQiLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgaWdub3JlLmNhc2UgPSBUUlVFKSkgJT4lIA0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCByb2JfYXNzZXNzbWVudF9tZXRob2QpICU+JSANCiAgICBjb3VudChyb2JfYXNzZXNzbWVudF9tZXRob2QsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShyb2JfYXNzZXNzbWVudF9tZXRob2QpICU+JSANCiAgICBmaWx0ZXIoc3VtKGZyZXEpID4gMikgICMgZmlsdGVyZWQgZm9yIHNjaWVudGljIGRhdGFiYXNlcyAgd2l0aCBtb3JlIHRoYW4gdHdvIG9jY3VycmVuY2VzIA0KDQoNCiMgQ3JlYXRlIHRoZSBBbGx1dmlhbCBwbG90DQpnZ3Bsb3Qocm9ibWV0aG9kX2FsbHV2aWFsLCBhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGF4aXMyID0gcm9iX2Fzc2Vzc21lbnRfbWV0aG9kKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIlJPQiBBc3Nlc3NtZW50IE1ldGhvZCIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS84LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDMpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQojIyBGaWd1cmUgeCAtIFRvdGFsIGNvdW50IGZvciBlYWNoIG1ldGhvZG9sb2d5IHVzZWQgdG8gdmlzdWFsaXNlIHRoZSByZXN1bHRzIG9mIHRoZSBtZXRhLWFuYWxzaXMNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQp2aXN1YWxpemF0aW9uX2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyh2aXN1YWxpemF0aW9uX21ldGhvZCwgc2VwID0gIixcXHMrIikgJT4lIA0KICBjb3VudCh2aXN1YWxpemF0aW9uX21ldGhvZCkgJT4lDQogIGZpbHRlcih2aXN1YWxpemF0aW9uX21ldGhvZCAhPSAiTkEiKSAlPiUNCiAgbXV0YXRlKHZpc3VhbGl6YXRpb25fbWV0aG9kID0gaWZlbHNlKG48PSAyLCAib3RoZXIiLCBhcy5jaGFyYWN0ZXIodmlzdWFsaXphdGlvbl9tZXRob2QpKSkgJT4lIA0KICAgIGdyb3VwX2J5KHZpc3VhbGl6YXRpb25fbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCnZpc3VhbGl6YXRpb25fcGN0IDwtIHZpc3VhbGl6YXRpb25fY291bnQgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gbiAvIHN1bSh2aXN1YWxpemF0aW9uX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQp2aXN1YWxpemF0aW9uX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcih2aXN1YWxpemF0aW9uX21ldGhvZCwgbiksIGZpbGwgPSAiIzAwNzAzMCIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuMyAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChkYXRhID0gdmlzdWFsaXphdGlvbl9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDApLCAiJSkiKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIGhqdXN0ID0gLTAuNywgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuLCB5ID0gcmVvcmRlcih2aXN1YWxpemF0aW9uX21ldGhvZCwgbikpLCB2anVzdCA9IDAuNSwgaGp1c3QgPSAtMC4yLCBzaXplID0gNCwgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwgMTAwKSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5Iiwgc2l6ZSA9IDAuNSksDQogICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSINCiAgKQ0KDQpgYGANCg0KIyMgRmlndXJlIHggLSBUb3RhbCBjb3VudCBmb3IgZWFjaCByZXBvcnRpbmcgZ3VpZGVsaW5lIGZvbGxvd2VkIGluIGVhY2ggbWV0YS1hbmFseXNpcw0KYGBge3J9DQoNCiMgQ2FsY3VsYXRlIHRoZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0KcmVwb3J0aW5nX2d1aWRlX2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhyZXBvcnRpbmdfc3RhbmRhcmRzX3R5cGUsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgY291bnQocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlKSAlPiUNCiAgZmlsdGVyKHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSAhPSAiTkEiKSAlPiUNCiAgbXV0YXRlKHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSA9IGlmZWxzZShuPD0gMiwgIm90aGVyIiwgYXMuY2hhcmFjdGVyKHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSkpKSAlPiUgDQogICAgZ3JvdXBfYnkocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCnJlcG9ydGluZ19ndWlkZV9wY3QgPC0gcmVwb3J0aW5nX2d1aWRlX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0ocmVwb3J0aW5nX2d1aWRlX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpyZXBvcnRpbmdfZ3VpZGVfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSwgbiksIGZpbGwgPSAiIzAwNzAzMCIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuMyAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChkYXRhID0gcmVwb3J0aW5nX2d1aWRlX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMCksICIlKSIpKSwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC45KSwgaGp1c3QgPSAtMC43LCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4sIHkgPSByZW9yZGVyKHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSwgbikpLCB2anVzdCA9IDAuNSwgaGp1c3QgPSAtMC4yLCBzaXplID0gNCwgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwgODApKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBzaXplID0gMC41KSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQoNCmBgYA0KDQpgYGB7cn0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCnJlcG9ydGluZ19zdGFuZGFyZHNfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgICBzZXBhcmF0ZV9yb3dzKEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBzZXAgPSAiL1xccysiKSAlPiUNCiAgICBmaWx0ZXIoIWdyZXBsKCJubyBjYXRlZ29yeSBmb3VuZCIsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBpZ25vcmUuY2FzZSA9IFRSVUUpKSAlPiUgDQogICAgZ3JvdXBfYnkoSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSkgJT4lIA0KICAgIGNvdW50KHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnkpICU+JSANCiAgICBzdW1tYXJpc2UoZnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIA0KICAgIGdyb3VwX2J5KHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSkgJT4lIA0KICAgIGZpbHRlcihzdW0oZnJlcSkgPiAyKSAgIyBmaWx0ZXJlZCBmb3Igc2NpZW50aWZpYyBkYXRhYmFzZXMgIHdpdGggbW9yZSB0aGFuIHR3byBvY2N1cnJlbmNlcyANCg0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZ2dwbG90KHJlcG9ydGluZ19zdGFuZGFyZHNfYWxsdXZpYWwsIGFlcyh5ID0gZnJlcSAsYXhpczEgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgYXhpczIgPSByZXBvcnRpbmdfc3RhbmRhcmRzX3R5cGUpKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkiLCAiUmVwb3J0aW5nIFN0YW5kYXJkcyBUeXBlIiksIGV4cGFuZCA9IGMoLjA1LCAuMDUpKSArDQogIHhsYWIoIlZhcmlhYmxlcyIpICsNCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzgsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gMykgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCiMgT2JqZWN0aXZlIDMgLSBUbyBpbnZlc3RpZ2F0ZSBjdXJyZW50IHJlcG9ydGluZyBwcmFjdGljZXMgaW4gZXhpc3RpbmcgbWV0YS1hbmFseXNlcyBleGFtaW5pbmcgdGhlIGltcGFjdHMgb2Ygb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcy4NCg0KIyMgU3VtbWFyeSBwbG90IGZvciBDRUVTQVQgZGF0YQ0KDQpDRUVTQVQgcmVzdWx0cyBhcmUgcHJlc2VudGVkIGFzIGEgcGVyY2VudGFnZSBvZiByZXN1bHQgcGVyIHF1ZXN0aW9uDQoNCmBgYHtyIHBsb3QgQ0VFU0FUIHN1bW1hcnkgfQ0KDQojIFN0YXJ0IHRoZSBkYXRhIG1hbmlwdWxhdGlvbg0KcGVyY2VudF9jZWVzYXRfc2NvcmUgPC0gc2QgJT4lDQogIGZpbHRlcighaXMubmEoYXV0aG9yX3llYXIpKSAlPiUNCiAgc2VsZWN0KHN0dWRpZXMgPSBhdXRob3JfeWVhciwgc3RhcnRzX3dpdGgoIkNFRSIpKSAlPiUNCiAgbmEub21pdCgpICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IC1zdHVkaWVzLCBuYW1lc190byA9ICJxdWVzdGlvbiIsIHZhbHVlc190byA9ICJzY29yZSIpICU+JQ0KICBncm91cF9ieShxdWVzdGlvbiwgc2NvcmUpICU+JQ0KICBzdW1tYXJpc2UobiA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lDQogIG11dGF0ZShwZXJjZW50ID0gKG4vc3VtKG4pKSoxMDApICU+JQ0KICBtdXRhdGUoYWNyb3NzKGMocXVlc3Rpb24sIHNjb3JlKSwgYXMuZmFjdG9yKSkgJT4lDQogIG11dGF0ZShxdWVzdGlvbiA9IGZhY3RvcihxdWVzdGlvbiwgbGV2ZWxzID0gcmV2KGxldmVscyhxdWVzdGlvbikpKSkgJT4lDQogIG11dGF0ZShzY29yZSA9IGZhY3RvcihzY29yZSwgbGV2ZWxzID0gbGV2ZWxzKHNjb3JlKVtjKDQsMSwzLDIpXSkpDQoNCg0KIyBQbG90IG9mIENFRVNBVCBzY29yZXMNCmdncGxvdChkYXRhID0gcGVyY2VudF9jZWVzYXRfc2NvcmUsIGFlcyh4ID0gcXVlc3Rpb24sIHkgPSBwZXJjZW50LCBmaWxsID0gc2NvcmUpKSArDQogIGdlb21fY29sKHdpZHRoID0gMC43LCBwb3NpdGlvbiA9ICJmaWxsIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMCwgMSkpICsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNGRjAwMDAiLCIjRkZENzAwIiwiIzAwODAwMCIsICIjREFBNTIwIiksIG5hbWUgPSAiU2NvcmU6IikgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCANCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIHlsYWIoIlByb3BvcnRpb24iKSArIA0KICB4bGFiKCJDRUVTQVQgUXVlc3Rpb24iKQ0KYGBgDQoNCiAtICoqT2JqZWN0aXZlIDQuCUJpYmxpb21ldHJpY3M6IEhvdyBpcyBzeW50aGVzaXplZCBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGUgZXZpZGVuY2UgY29ubmVjdGVkPyoqIFdlIHdpbGwgaW52ZXN0aWdhdGUgdGhlIGNvdW50cmllcyBhbmQgaW5zdGl0dXRpb25zIHRoYXQgYXJlIHByaW1hcmlseSBlbmdhZ2VkIGluIHNlY29uZGFyeSByZXNlYXJjaCBvbiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzLCBhbmQgYW5hbHl6ZSB0aGUgbmV0d29ya3MgdGhhdCBleGlzdCBiZXR3ZWVuIHRoZW0uIEJ5IGRvaW5nIHNvLCB3ZSBob3BlIHRvIGdhaW4gaW5zaWdodHMgaW50byB0aGUgY29sbGFib3JhdGl2ZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gZGlmZmVyZW50IGluc3RpdHV0aW9ucyBhbmQgaWRlbnRpZnkgYW55IHBhdHRlcm5zIG9yIHRyZW5kcyBpbiB0aGUgZGlzdHJpYnV0aW9uIG9mIHJlc2VhcmNoIGVmZm9ydHMuDQoNCmBgYHtyfQ0KZmlnNWEgPC0gYmlibGlvQW5hbHlzaXMoYmliX3NjbykNCnBsb3QoZmlnNWEpDQpgYGANCiMjIGZpZzViIC0gY28tb2NjdXJhbmNlIG1hdHJpeA0KYGBge3J9DQpOZXRNYXRyaXhfa2V5d29yZHMgPC0gYmlibGlvTmV0d29yayhiaWJfc2NvLCBhbmFseXNpcyA9ICJjby1vY2N1cnJlbmNlcyIsIG5ldHdvcmsgPSAia2V5d29yZHMiLCBzZXAgPSAiOyIpDQpmaWc1YiA8LSBuZXR3b3JrUGxvdChOZXRNYXRyaXhfa2V5d29yZHMsIG5vcm1hbGl6ZT0iYXNzb2NpYXRpb24iLCBuID0gMTAsIA0KICAgICAgICAgICAgICAgICAgICAgVGl0bGUgPSAiS2V5d29yZCBDby1vY2N1cnJlbmNlcyIsIHR5cGUgPSAiZnJ1Y2h0ZXJtYW4iLCANCiAgICAgICAgICAgICAgICAgICAgIHNpemUuY2V4ID0gVFJVRSwgc2l6ZSA9IDEwLCByZW1vdmUubXVsdGlwbGUgPSBGLCANCiAgICAgICAgICAgICAgICAgICAgIGVkZ2VzaXplID0gNCwgbGFiZWxzaXplID0gMywgbGFiZWwuY2V4ID0gVFJVRSwgDQogICAgICAgICAgICAgICAgICAgICBlZGdlcy5taW4gPSAyLCBsYWJlbC5uID0gOSwgYWxwaGEgPSAwLjMpIA0KYGBgDQoNCiMjIGZpZzVjIC0gdGhlbWF0aWMgbWFwIGJhc2VkIG9uIGtleXdvcmRzDQpgYGB7cn0NCnBhcihtZnJvdz1jKDEsMSksIG1hcj1jKDAsMiwwLDIpKQ0KZmlnNWMgPC0gdGhlbWF0aWNNYXAoYmliX3NjbywgZmllbGQgPSAiSUQiLCBuID0gMjAwMCwgbWluZnJlcSA9IDUsIHN0ZW1taW5nID0gRkFMU0UsIHNpemUgPSAwLjUsIG4ubGFiZWxzID0gMSwgcmVwZWwgPSBUUlVFKQ0KcGxvdChmaWc1YyRtYXApDQoNCmBgYA0KDQojIyBmaWcgNWQgLSBhdXRob3IgY29sbGFib3JhdGlvbiBuZXR3b3JrDQpgYGB7cn0NCk5ldE1hdHJpeF9hdXRob3JzIDwtIGJpYmxpb05ldHdvcmsoYmliX3NjbywgYW5hbHlzaXMgPSAiY29sbGFib3JhdGlvbiIsICBuZXR3b3JrID0gImF1dGhvcnMiLCBzZXAgPSAiOyIpDQpmaWc1ZCA8LSBuZXR3b3JrUGxvdChOZXRNYXRyaXhfYXV0aG9ycywgIG4gPSAxMDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaXRsZSA9ICJBdXRob3IgY29sbGFib3JhdGlvbiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gImF1dG8iLCBzaXplID0gNCwgc2l6ZS5jZXggPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWRnZXNpemUgPSAxMCwgbGFiZWxzaXplID0gMS4xKQ0KYGBgDQoNCiMjIGZpZzVlIC0gY291bnRyeSBwdWJsaWNhdGlvbnMgbWFwDQpgYGB7cn0NCg0KYmlibWFwIDwtIG1ldGFUYWdFeHRyYWN0aW9uKGJpYl9zY28sIEZpZWxkID0gIkFVMV9DTyIsIHNlcCA9ICI7IikgDQpiaWJtYXAgPC0gbWV0YVRhZ0V4dHJhY3Rpb24oYmlibWFwLCBGaWVsZCA9ICJBVV9DTyIsIHNlcCA9ICI7IikgDQojc2F2ZSBjb3VudHMgaW4gYSBkYXRhIGZyYW1lDQpmaXJzdGNvdW50cnljb3VudHMgPC0gYmlibWFwICU+JSANCiAgZ3JvdXBfYnkoQVUxX0NPKSAlPiUNCiAgY291bnQoKSAlPiUgDQogIGZpbHRlcighaXMubmEoQVUxX0NPKSkgIA0KI2xvYWQgbWFwIGRhdGENCndvcmxkX21hcCA8LSBtYXBfZGF0YSgid29ybGQiKSAlPiUgDQogIGZpbHRlcighIGxvbmcgPiAxODApICNyZW1vdmUgY291bnRyaWVzIHdpdGggbG9uZ2l0dWRlID4xODAgdG8gbWFrZSBlcXVhbCBwcm9qZWN0aW9uLWxpa2UgbWFwIHdpdGhvdXQgYXJ0aWZhY3RzDQojIEZvcm1hdCBjb3VudHJ5IG5hbWVzIHRvIG1hdGNoIHJlZ2lvbnMgb24gdGhlIHdvcmxkIG1hcA0KZmlyc3Rjb3VudHJ5Y291bnRzJHJlZ2lvbiA8LSBzdHJfdG9fdGl0bGUoZmlyc3Rjb3VudHJ5Y291bnRzJEFVMV9DTykNCmZpcnN0Y291bnRyeWNvdW50cyRyZWdpb25bZmlyc3Rjb3VudHJ5Y291bnRzJHJlZ2lvbiA9PSAiVXNhIl0gPC0gIlVTQSIgI0ZpeCAiVXNhIiB0byAiVVNBIiA6DQpmaXJzdGNvdW50cnljb3VudHMkcmVnaW9uW2ZpcnN0Y291bnRyeWNvdW50cyRyZWdpb24gPT0gIlVuaXRlZCBLaW5nZG9tIl0gPC0gIlVLIiAjZml4IHRvICJVSyINCiMoZmlyc3Rjb3VudHJ5Y291bnRzJHJlZ2lvbikgJWluJSB3b3JsZF9tYXAkcmVnaW9uICNjaGVjayBtYXRjaGluZw0KIyMgY29sb3VyIGFsbCByZWdpb25zIG9uIHRoZSBtYXA6DQplbXB0eW1hcCA8LSB0aWJibGUocmVnaW9uID0gdW5pcXVlKHdvcmxkX21hcCRyZWdpb24pLCBuID0gcmVwKDAsbGVuZ3RoKHVuaXF1ZSh3b3JsZF9tYXAkcmVnaW9uKSkpKSAjY3JlYXRlIHRhYmxlIHdpdGggYWxsIGNvdW50cyBhcyAwDQpmdWxsbWFwIDwtIGxlZnRfam9pbihlbXB0eW1hcCwgZmlyc3Rjb3VudHJ5Y291bnRzLCBieSA9ICJyZWdpb24iKSAjam9pbiB3aXRoIGFjdHVhbCBjb3VudHMgdGFibGUNCmZ1bGxtYXAkbiA8LSBmdWxsbWFwJG4ueCArIGZ1bGxtYXAkbi55ICMgbWFrZSBuZXcgY29sdW1uIGZvciBmaXhlZCBjb3VudHMNCmZ1bGxtYXAkbltpcy5uYShmdWxsbWFwJG4pXSA8LSAwICNjaGFuZ2UgTkEgdG8gMCBmb3IgcmVnaW9ucyB3aXRoIG5vIGNvdW50cw0KZmlnNWUgPC0gZnVsbG1hcCAlPiUgDQogIGdncGxvdChhZXMoZmlsbCA9IG4sIG1hcF9pZCA9IHJlZ2lvbikpICsNCiAgZ2VvbV9tYXAobWFwID0gd29ybGRfbWFwLCBjb2xvciA9ICJibGFjayIpICsNCiAgZXhwYW5kX2xpbWl0cyh4ID0gd29ybGRfbWFwJGxvbmcsIHkgPSB3b3JsZF9tYXAkbGF0KSArDQogIGNvb3JkX21hcCgibW9sbCIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJyaWdodCIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiIzk4RkI5OCIsIGhpZ2ggPSAiIzAwNjQwMCIsDQogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiU2NvcmUiLCBuYS52YWx1ZSA9ICJncmF5NzAiLA0KIGxpbWl0cyA9IGMoMSwgMjApLA0KICAgICAgZ3VpZGUgPSBndWlkZV9jb2xvcmJhcihkaXJlY3Rpb24gPSAidmVydGljYWwuIikpICsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9jb2xvdXJiYXIoYmFyd2lkdGggPSB1bml0KDE1LCB1bml0cyA9ICJtbSIpLCBiYXJoZWlnaHQgPSB1bml0KDIwLCB1bml0cyA9ICJtbSIpKSkNCmZpZzVlDQpgYGANCg0KIyMgTWFwIG9mIGV1cm9wZSANCmBgYHtyfQ0KZmlnNWYgPC0gZnVsbG1hcCAlPiUgDQogIGdncGxvdChhZXMoZmlsbCA9IG4sIG1hcF9pZCA9IHJlZ2lvbikpICsNCiAgZ2VvbV9tYXAobWFwID0gd29ybGRfbWFwLCBjb2xvciA9ICJibGFjayIpICsNCiAgY29vcmRfbWFwKCJtb2xsIiwgeWxpbSA9IGMoMzAsIDc1KSwgeGxpbSA9IGMoLTI1LCA0NSkpICsgIyBzZXQgbGltaXRzIGZvciBFdXJvcGUNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjOThGQjk4IiwgaGlnaCA9ICIjMDA2NDAwIiwNCiAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gIlNjb3JlIiwgbmEudmFsdWUgPSAiZ3JheTcwIiwNCiAgICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDEsIDEwKSwNCiAgICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2NvbG9yYmFyKGRpcmVjdGlvbiA9ICJ2ZXJ0aWNhbC4iKSkgKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG91cmJhcihiYXJ3aWR0aCA9IHVuaXQoMTUsIHVuaXRzID0gIm1tIiksIGJhcmhlaWdodCA9IHVuaXQoMjAsIHVuaXRzID0gIm1tIikpKQ0KDQpmaWc1Zg0KDQoNCmBgYA0KDQojIyBmaWc1ZiAtIGNvdW50cnkgY29sbGFib3JhdGlvbiBuZXR3b3JrIGNpcmNsZSBwbG90DQpgYGB7cn0NCiMgRXh0cmFjdCBjb3VudHJpZXMgZnJvbSB0aGUgYWZmaWxpYXRpb25zDQpiaWJfc2NvMiA8LSBtZXRhVGFnRXh0cmFjdGlvbihiaWJfc2NvLCBGaWVsZCA9ICJBVV9DTyIsIHNlcCA9ICI7IikNCg0KIyBDcmVhdGUgYSBuZXR3b3JrIG1hdHJpeCBvZiBjb2xsYWJvcmF0aW9ucyBiZXR3ZWVuIGNvdW50cmllcw0KTmV0TWF0cml4X2NvdW50cnkgPC0gYmlibGlvTmV0d29yayhiaWJfc2NvMiwgYW5hbHlzaXMgPSAiY29sbGFib3JhdGlvbiIsIG5ldHdvcmsgPSAiY291bnRyaWVzIiwgc2VwID0gIjsiKQ0KDQojIENvbnZlcnQgdGhlIG5ldHdvcmsgbWF0cml4IHRvIGEgc3RhbmRhcmQgbWF0cml4DQpOZXRNYXRyaXhfY291bnRyeSA8LSBhcy5tYXRyaXgoTmV0TWF0cml4X2NvdW50cnkpDQoNCiMgUmVtb3ZlIHRoZSBsb3dlciB0cmlhbmdsZSAoYXMgdGhpcyBpcyBkdXBsaWNhdGlvbiBvZiBpbmZvKQ0KTmV0TWF0cml4X2NvdW50cnlbbG93ZXIudHJpKE5ldE1hdHJpeF9jb3VudHJ5KV0gPC0gMCANCg0KIyBDaGFuZ2UgY29sdW1uIGFuZCByb3cgbmFtZXMgdG8gdGl0bGUgY2FzZQ0KY29sbmFtZXMoTmV0TWF0cml4X2NvdW50cnkpIDwtIHN0cl90b190aXRsZShjb2xuYW1lcyhOZXRNYXRyaXhfY291bnRyeSkpDQpyb3duYW1lcyhOZXRNYXRyaXhfY291bnRyeSkgPC0gc3RyX3RvX3RpdGxlKHJvd25hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSkNCg0KIyBDaGFuZ2UgIlVzYSIgdG8gIlVTQSINCmNvbG5hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KVtjb2xuYW1lcyhOZXRNYXRyaXhfY291bnRyeSkgPT0gIlVzYSJdIDwtICJVU0EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY291bnRyeSlbcm93bmFtZXMoTmV0TWF0cml4X2NvdW50cnkpID09ICJVc2EiXSA8LSAiVVNBIg0KDQojIENoYW5nZSAiVW5pdGVkIEtpbmdkb20iIHRvICJVSyIgZm9yIGVhc2llciBwbG90dGluZw0KY29sbmFtZXMoTmV0TWF0cml4X2NvdW50cnkpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSA9PSAiVW5pdGVkIEtpbmdkb20iXSA8LSAiVUsiDQpyb3duYW1lcyhOZXRNYXRyaXhfY291bnRyeSlbcm93bmFtZXMoTmV0TWF0cml4X2NvdW50cnkpID09ICJVbml0ZWQgS2luZ2RvbSJdIDwtICJVSyINCg0KIyBEZWZpbmUgY29sb3JzIGZvciBlYWNoIGNvdW50cnkNCm15LmNvbHMyIDwtIGMoDQogIFVTQSA9ICIjMzc3ZWI4IiwNCiAgU3BhaW4gPSAiI2ZmZmYzMyIsDQogIENoaW5hID0gIiNlNDFhMWMiLA0KICBGcmFuY2UgPSAiIzk5OTk5OSIsDQogIENhbmFkYSA9ICIjYTZjZWUzIiwNCiAgRGVubWFyayA9ICIjYjJkZjhhIiwNCiAgTmV0aGVybGFuZHMgPSAiIzM3N2ViOCIsDQogIEJlbGdpdW0gPSAiIzk4NGVhMyIsDQogIFVLID0gIiNmZmZmMzMiLA0KICBBdXN0cmFsaWEgPSAiIzRkYWY0YSIsDQogIEJyYXppbCA9ICIjNGRhZjRhIiwNCiAgR2VybWFueSA9ICIjYjJkZjhhIiwNCiAgR3JlZWNlID0gIiNmNzgxYmYiLA0KICBLb3JlYSA9ICIjZjc4MWJmIiwNCiAgSXJlbGFuZCA9ICIjYTY1NjI4IiwNCiAgTm9yd2F5ID0gIiNmZjdmMDAiLA0KICBTd2VkZW4gPSAiIzRkYWY0YSIsDQogIEVneXB0ID0gIiNmNzgxYmYiLA0KICBJdGFseSA9ICIjZTQxYTFjIiwNCiAgSmFwYW4gPSAiIzFmNzhiNCIsDQogIFN3aXR6ZXJsYW5kID0gIiM5ODRlYTMiLA0KICBUdXJrZXkgPSAiIzMzYTAyYyIsDQogIEF1c3RyaWEgPSAiI2IyZGY4YSIsDQogIElzcmFlbCA9ICIjZjc4MWJmIiwNCiAgTmV3WmVhbGFuZCA9ICIjNGRhZjRhIiwNCiAgUnVzc2lhID0gIiM5OTk5OTkiLA0KICBTaW5nYXBvcmUgPSAiI2IyZGY4YSIsDQogIFBvcnR1Z2FsID0gIiM5ODRlYTMiLA0KICBGaW5sYW5kID0gIiNiMmRmOGEiLA0KICBNZXhpY28gPSAiI2E2NTYyOCIsDQogIFBvbGFuZCA9ICIjYjJkZjhhIiwNCiAgU291dGhBZnJpY2EgPSAiI2Y3ODFiZiIsDQogIEFyZ2VudGluYSA9ICIjZmY3ZjAwIiwNCiAgQ2hpbGUgPSAiI2ZmN2YwMCIsDQogIEN6ZWNoUmVwdWJsaWMgPSAiI2IyZGY4YSIsDQogIEljZWxhbmQgPSAiI2IyZGY4YSIsDQogIFBlcnUgPSAiI2ZmN2YwMCIsDQogIFJvbWFuaWEgPSAiI2ZiOWE5OSIsDQogIFNlcmJpYSA9ICIjZmI5YTk5IiwNCiAgVUFFID0gIiNhNjU2MjgiDQopDQoNCg0KIyBDcmVhdGUgYSBjaG9yZCBkaWFncmFtIG9mIHRoZSBuZXR3b3JrIG1hdHJpeA0KZmlnNWYgPC0gY2hvcmREaWFncmFtKE5ldE1hdHJpeF9jb3VudHJ5LCBhbm5vdGF0aW9uVHJhY2sgPSAiZ3JpZCIsIHByZUFsbG9jYXRlVHJhY2tzID0gMSwgZ3JpZC5jb2wgPSBteS5jb2xzMikNCg0KIyBBZGQgYSB0cmFjayB0byBsYWJlbCBlYWNoIHNlY3RvciB3aXRoIGl0cyBuYW1lDQpjaXJjb3MudHJhY2tQbG90UmVnaW9uKHRyYWNrLmluZGV4ID0gMSwgcGFuZWwuZnVuID0gZnVuY3Rpb24oeCwgeSkgew0KICB4bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ4bGltIikNCiAgeWxpbSA9IGdldC5jZWxsLm1ldGEuZGF0YSgieWxpbSIpDQogIHNlY3Rvci5uYW1lID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJzZWN0b3IuaW5kZXgiKQ0KICBjaXJjb3MudGV4dChtZWFuKHhsaW0pLCB5bGltWzFdICsgLjEsIHNlY3Rvci5uYW1lLCBmYWNpbmcgPSAiY2xvY2t3aXNlIiwgbmljZUZhY2luZyA9IFRSVUUsIGFkaiA9IGMoMCwgMC41KSkNCiAgY2lyY29zLmF4aXMoaCA9ICJ0b3AiLCBsYWJlbHMuY2V4ID0gMC41LCBtYWpvci50aWNrLmxlbmd0aCA9IDAuNSwgc2VjdG9yLmluZGV4ID0gc2VjdG9yLm5hbWUsIHRyYWNrLmluZGV4ID0gMikNCn0sIGJnLmJvcmRlciA9IE5BKQ0KDQpgYGANCg0KIyMgZmlnNWcgY29sbGFib3JhdGlvbiBtYXRyaXggd2l0aCBzZWxmIGNpdGF0aW9uIHJlbW92ZWQNCmBgYHtyfQ0KDQpkaWFnKE5ldE1hdHJpeF9jb3VudHJ5KSA8LSAwDQoNCiMgQ3JlYXRlIGEgY2hvcmQgZGlhZ3JhbSBvZiB0aGUgbmV0d29yayBtYXRyaXgNCmZpZzVnIDwtIGNob3JkRGlhZ3JhbShOZXRNYXRyaXhfY291bnRyeSwgYW5ub3RhdGlvblRyYWNrID0gImdyaWQiLCBwcmVBbGxvY2F0ZVRyYWNrcyA9IDEsIGdyaWQuY29sID0gbXkuY29sczIpDQoNCiMgQWRkIGEgdHJhY2sgdG8gbGFiZWwgZWFjaCBzZWN0b3Igd2l0aCBpdHMgbmFtZQ0KY2lyY29zLnRyYWNrUGxvdFJlZ2lvbih0cmFjay5pbmRleCA9IDEsIHBhbmVsLmZ1biA9IGZ1bmN0aW9uKHgsIHkpIHsNCiAgeGxpbSA9IGdldC5jZWxsLm1ldGEuZGF0YSgieGxpbSIpDQogIHlsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInlsaW0iKQ0KICBzZWN0b3IubmFtZSA9IGdldC5jZWxsLm1ldGEuZGF0YSgic2VjdG9yLmluZGV4IikNCiAgY2lyY29zLnRleHQobWVhbih4bGltKSwgeWxpbVsxXSArIC4xLCBzZWN0b3IubmFtZSwgZmFjaW5nID0gImNsb2Nrd2lzZSIsIG5pY2VGYWNpbmcgPSBUUlVFLCBhZGogPSBjKDAsIDAuNSkpDQogIGNpcmNvcy5heGlzKGggPSAidG9wIiwgbGFiZWxzLmNleCA9IDAuNSwgbWFqb3IudGljay5sZW5ndGggPSAwLjIsIHNlY3Rvci5pbmRleCA9IHNlY3Rvci5uYW1lLCB0cmFjay5pbmRleCA9IDIpDQp9LCBiZy5ib3JkZXIgPSBOQSkNCmBgYA0KDQojIyBmaWcgNWggY29udGl0bmVudCBjb2xsYWJvcmF0aW9uIA0KYGBge3J9DQoNCg0KTmV0TWF0cml4X2NvbnRpbmVudCA8LSBOZXRNYXRyaXhfY291bnRyeQ0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlVTQSJdIDwtICJOb3J0aCBBbWVyaWNhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlVTQSJdIDwtICJOb3J0aCBBbWVyaWNhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU3BhaW4iXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlNwYWluIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkNoaW5hIl0gPC0gIkFzaWEiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ2hpbmEiXSA8LSAiQXNpYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkZyYW5jZSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRnJhbmNlIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkNhbmFkYSJdIDwtICJOb3J0aCBBbWVyaWNhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkNhbmFkYSJdIDwtICJOb3J0aCBBbWVyaWNhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRGVubWFyayJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRGVubWFyayJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJOZXRoZXJsYW5kcyJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiTmV0aGVybGFuZHMiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQmVsZ2l1bSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQmVsZ2l1bSJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJVSyJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVUsiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQXVzdHJhbGlhIl0gPC0gIkF1c3RyYWxpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJBdXN0cmFsaWEiXSA8LSAiQXVzdHJhbGlhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQnJhemlsIl0gPC0gIlNvdXRoIEFtZXJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQnJhemlsIl0gPC0gIlNvdXRoIEFtZXJpY2EiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJHZXJtYW55Il0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJHZXJtYW55Il0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkZpbmxhbmQiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkZpbmxhbmQiXSA8LSAiRXVyb3BlIg0KDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJHcmVlY2UiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkdyZWVjZSJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJLb3JlYSJdIDwtICJBc2lhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIktvcmVhIl0gPC0gIkFzaWEiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJOb3J3YXkiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIk5vcndheSJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJTd2VkZW4iXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlN3ZWRlbiJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJFZ3lwdCJdIDwtICJBZnJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRWd5cHQiXSA8LSAiQWZyaWNhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSXRhbHkiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkl0YWx5Il0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkphcGFuIl0gPC0gIkFzaWEiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSmFwYW4iXSA8LSAiQXNpYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlBvcnR1Z2FsIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJQb3J0dWdhbCJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJTd2l0emVybGFuZCJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU3dpdHplcmxhbmQiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVHVya2V5Il0gPC0gIkFzaWEiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVHVya2V5Il0gPC0gIkFzaWEiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJJbmRpYSJdIDwtICJBc2lhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkluZGlhIl0gPC0gIkFzaWEiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJJcmFuIl0gPC0gIkFzaWEiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSXJhbiJdIDwtICJBc2lhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ29zdGEgUmljYSJdIDwtICJOb3J0aCBBbWVyaWNhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkNvc3RhIFJpY2EiXSA8LSAiTm9ydGggQW1lcmljYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkN6ZWNoIFJlcHVibGljIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJDemVjaCBSZXB1YmxpYyJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJIb25nIEtvbmciXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJIb25nIEtvbmciXSA8LSAiQXNpYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkljZWxhbmQiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkljZWxhbmQiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSXJlbGFuZCJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSXJlbGFuZCJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJNZXhpY28iXSA8LSAiTm9ydGggQW1lcmljYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJNZXhpY28iXSA8LSAiTm9ydGggQW1lcmljYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlJvbWFuaWEiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlJvbWFuaWEiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU2xvdmFraWEiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlNsb3Zha2lhIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlVrcmFpbmUiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlVrcmFpbmUiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQXVzdHJhbGlhIl0gPC0gIk9jZWFuaWEiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQXVzdHJhbGlhIl0gPC0gIk9jZWFuaWEiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJLYXpha2hzdGFuIl0gPC0gIkFzaWEiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiS2F6YWtoc3RhbiJdIDwtICJBc2lhIg0KDQoNCiMgY29sbGFwc2luZw0KbWVyZ2VfbWF0cml4IDwtIHQocm93c3VtKHQoTmV0TWF0cml4X2NvbnRpbmVudCksIGdyb3VwID0gY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCksIG5hLnJtID0gVCkpDQptZXJnZV9tYXRyaXgyIDwtIHJvd3N1bShtZXJnZV9tYXRyaXgsIGdyb3VwID0gcm93bmFtZXMobWVyZ2VfbWF0cml4KSkNCiMgcmVtb3ZlIGRpYWdvbmFsIGVsZW1lbnRzDQpkaWFnKG1lcmdlX21hdHJpeDIpIDwtIDANCiMgY2hvcmQgcGxvdA0KY2hvcmREaWFncmFtRnJvbU1hdHJpeChtZXJnZV9tYXRyaXgyKQ0KDQojIERlZmluZSBjb2xvcnMgZm9yIGVhY2ggY29udGluZW50DQpteS5jb2xzMiA8LSBjKA0KICBBZnJpY2EgPSAiI0NDNzlBNyIsDQogIE5vcnRoQW1lcmljYSA9ICIjRjBFNDQyIiwNCiAgQXNpYSA9ICIjMDA3MkIyIiwNCiAgRXVyb3BlID0gIiNFNjlGMDAiLA0KICBPY2VhbmlhID0gIiMwMDlFNzMiLA0KICBTb3V0aEFtZXJpY2EgPSAiI0Q1NUUwMCINCikNCg0KDQojIENyZWF0ZSBhIGNob3JkIGRpYWdyYW0gb2YgdGhlIG5ldHdvcmsgbWF0cml4DQpmaWc1aCA8LSBjaG9yZERpYWdyYW0obWVyZ2VfbWF0cml4MiwgYW5ub3RhdGlvblRyYWNrID0gImdyaWQiLCBwcmVBbGxvY2F0ZVRyYWNrcyA9IDEpDQojIEFkZCBhIHRyYWNrIHRvIGxhYmVsIGVhY2ggc2VjdG9yIHdpdGggaXRzIG5hbWUNCmNpcmNvcy50cmFja1Bsb3RSZWdpb24odHJhY2suaW5kZXggPSAxLCBwYW5lbC5mdW4gPSBmdW5jdGlvbih4LCB5KSB7DQogIHhsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInhsaW0iKQ0KICB5bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ5bGltIikNCiAgc2VjdG9yLm5hbWUgPSBnZXQuY2VsbC5tZXRhLmRhdGEoInNlY3Rvci5pbmRleCIpDQogIGNpcmNvcy50ZXh0KG1lYW4oeGxpbSksIHlsaW1bMV0gKyAwLjIsIHNlY3Rvci5uYW1lLCBmYWNpbmcgPSAiY2xvY2t3aXNlIiwgbmljZUZhY2luZyA9IFRSVUUsIGFkaiA9IGMoMCwgMC41KSkNCiAgY2lyY29zLmF4aXMoaCA9ICJ0b3AiLCBsYWJlbHMuY2V4ID0gMC41LCBtYWpvci50aWNrLmxlbmd0aCA9IDAuMiwgc2VjdG9yLmluZGV4ID0gc2VjdG9yLm5hbWUsIHRyYWNrLmluZGV4ID0gMikNCn0sIGJnLmJvcmRlciA9IE5BKQ0KDQpgYGANCg0KDQoNCmBgYHtyIG1vc3QgY2l0ZWQgYXJ0aWNsZXMgYW5kIGF1dGhvcnN9DQoNCkNSIDwtIGNpdGF0aW9ucyhiaWJfc2NvLCBmaWVsZCA9ICJhcnRpY2xlIiwgc2VwID0gIjsiKSAjbGlzdCBvZiBtb3N0IGNpdGVkIGFydGljbGVzDQogY2JpbmQoQ1IkQ2l0ZWRbMToxMF0pICN0ZW4gbW9zdCBjaXRlZCBhcnRpY2xlcw0KIA0KQ1IgPC0gY2l0YXRpb25zKGJpYl9zY28sIGZpZWxkID0gImF1dGhvciIsIHNlcCA9ICI7IikNCmNiaW5kKENSJENpdGVkWzE6MTBdKSAjdGVuIG1vc3QgY2l0ZWQgYXV0aG9ycw0KYGBgIA0KDQpgYGB7ciBiaWJsaW9tZXRyaWMgY291cGxpbmcgbmV0d29ya30NCk5ldE1hdHJpeF9jb3VwbGluZyA8LSBiaWJsaW9OZXR3b3JrKGJpYl9zY28sIGFuYWx5c2lzID0gImNvdXBsaW5nIiwgbmV0d29yayA9ICJyZWZlcmVuY2VzIiwgc2VwID0gIjsgIikNCk5ldE1hdHJpeF9jb3VwbGluZ19wbG90IDwtIG5ldHdvcmtQbG90KE5ldE1hdHJpeF9jb3VwbGluZywgbiA9IDIwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpdGxlID0gIlBhcGVyIGNvLWNpdGF0aW9uIiwgdHlwZSA9ICJmcnVjaHRlcm1hbiIsIHNpemU9VCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUubXVsdGlwbGU9RkFMU0UsIGxhYmVsc2l6ZT0wLjgsZWRnZXNpemUgPSA1KQ0KYGBgDQoNCg0K